mysqladm/client/
commands.rs

1mod create_db;
2mod create_user;
3mod drop_db;
4mod drop_user;
5mod edit_db_privs;
6mod lock_user;
7mod passwd_user;
8mod show_db;
9mod show_db_privs;
10mod show_user;
11mod unlock_user;
12
13pub use create_db::*;
14pub use create_user::*;
15pub use drop_db::*;
16pub use drop_user::*;
17pub use edit_db_privs::*;
18pub use lock_user::*;
19pub use passwd_user::*;
20pub use show_db::*;
21pub use show_db_privs::*;
22pub use show_user::*;
23pub use unlock_user::*;
24
25use clap::Parser;
26
27use crate::core::protocol::{ClientToServerMessageStream, Response};
28
29#[derive(Parser, Debug, Clone)]
30pub enum ClientCommand {
31    /// Create one or more databases
32    #[command()]
33    CreateDb(CreateDbArgs),
34
35    /// Delete one or more databases
36    #[command()]
37    DropDb(DropDbArgs),
38
39    /// Print information about one or more databases
40    ///
41    /// If no database name is provided, all databases you have access will be shown.
42    #[command()]
43    ShowDb(ShowDbArgs),
44
45    /// Print user privileges for one or more databases
46    ///
47    /// If no database names are provided, all databases you have access to will be shown.
48    #[command()]
49    ShowDbPrivs(ShowDbPrivsArgs),
50
51    /// Change user privileges for one or more databases. See `edit-db-privs --help` for details.
52    ///
53    /// This command has two modes of operation:
54    ///
55    /// 1. Interactive mode: If nothing else is specified, the user will be prompted to edit the privileges using a text editor.
56    ///
57    ///    You can configure your preferred text editor by setting the `VISUAL` or `EDITOR` environment variables.
58    ///
59    ///    Follow the instructions inside the editor for more information.
60    ///
61    /// 2. Non-interactive mode: If the `-p` flag is specified, the user can write privileges using arguments.
62    ///
63    ///    The privilege arguments should be formatted as `<db>:<user>+<privileges>-<privileges>`
64    ///    where the privileges are a string of characters, each representing a single privilege.
65    ///    The character `A` is an exception - it represents all privileges.
66    ///
67    ///    The character-to-privilege mapping is defined as follows:
68    ///
69    ///    - `s` - SELECT
70    ///    - `i` - INSERT
71    ///    - `u` - UPDATE
72    ///    - `d` - DELETE
73    ///    - `c` - CREATE
74    ///    - `D` - DROP
75    ///    - `a` - ALTER
76    ///    - `I` - INDEX
77    ///    - `t` - CREATE TEMPORARY TABLES
78    ///    - `l` - LOCK TABLES
79    ///    - `r` - REFERENCES
80    ///    - `A` - ALL PRIVILEGES
81    ///
82    ///   If you provide a database name, you can omit it from the privilege string,
83    ///   e.g. `edit-db-privs my_db -p my_user+siu` is equivalent to `edit-db-privs -p my_db:my_user:siu`.
84    ///   While it doesn't make much of a difference for a single edit, it can be useful for editing multiple users
85    ///   on the same database at once.
86    ///
87    ///   Example usage of non-interactive mode:
88    ///
89    ///     Enable privileges `SELECT`, `INSERT`, and `UPDATE` for user `my_user` on database `my_db`:
90    ///
91    ///       `mysqladm edit-db-privs -p my_db:my_user:siu`
92    ///
93    ///     Enable all privileges for user `my_other_user` on database `my_other_db`:
94    ///
95    ///       `mysqladm edit-db-privs -p my_other_db:my_other_user:A`
96    ///
97    ///     Set miscellaneous privileges for multiple users on database `my_db`:
98    ///
99    ///       `mysqladm edit-db-privs my_db -p my_user:siu my_other_user:ct``
100    ///
101    #[command(verbatim_doc_comment)]
102    EditDbPrivs(EditDbPrivsArgs),
103
104    /// Create one or more users
105    #[command()]
106    CreateUser(CreateUserArgs),
107
108    /// Delete one or more users
109    #[command()]
110    DropUser(DropUserArgs),
111
112    /// Change the MySQL password for a user
113    #[command()]
114    PasswdUser(PasswdUserArgs),
115
116    /// Print information about one or more users
117    ///
118    /// If no username is provided, all users you have access will be shown.
119    #[command()]
120    ShowUser(ShowUserArgs),
121
122    /// Lock account for one or more users
123    #[command()]
124    LockUser(LockUserArgs),
125
126    /// Unlock account for one or more users
127    #[command()]
128    UnlockUser(UnlockUserArgs),
129}
130
131pub async fn handle_command(
132    command: ClientCommand,
133    server_connection: ClientToServerMessageStream,
134) -> anyhow::Result<()> {
135    match command {
136        ClientCommand::CreateDb(args) => create_databases(args, server_connection).await,
137        ClientCommand::DropDb(args) => drop_databases(args, server_connection).await,
138        ClientCommand::ShowDb(args) => show_databases(args, server_connection).await,
139        ClientCommand::ShowDbPrivs(args) => show_database_privileges(args, server_connection).await,
140        ClientCommand::EditDbPrivs(args) => edit_database_privileges(args, server_connection).await,
141        ClientCommand::CreateUser(args) => create_users(args, server_connection).await,
142        ClientCommand::DropUser(args) => drop_users(args, server_connection).await,
143        ClientCommand::PasswdUser(args) => passwd_user(args, server_connection).await,
144        ClientCommand::ShowUser(args) => show_users(args, server_connection).await,
145        ClientCommand::LockUser(args) => lock_users(args, server_connection).await,
146        ClientCommand::UnlockUser(args) => unlock_users(args, server_connection).await,
147    }
148}
149
150pub fn erroneous_server_response(
151    response: Option<Result<Response, std::io::Error>>,
152) -> anyhow::Result<()> {
153    match response {
154        Some(Ok(Response::Error(e))) => {
155            anyhow::bail!("Server returned error: {}", e);
156        }
157        Some(Err(e)) => {
158            anyhow::bail!(e);
159        }
160        Some(response) => {
161            anyhow::bail!("Unexpected response from server: {:?}", response);
162        }
163        None => {
164            anyhow::bail!("No response from server");
165        }
166    }
167}