sql_from_models_cli/opt.rs
1use anyhow::Result;
2use sqlx::migrate::{MigrateError, Migrator};
3use std::path::Path;
4use structopt::StructOpt;
5#[derive(StructOpt, Debug)]
6pub struct Opt {
7 #[structopt(subcommand)]
8 pub command: Command,
9}
10
11#[derive(StructOpt, Debug)]
12pub enum Command {
13 #[structopt(alias = "db")]
14 Database(DatabaseOpt),
15
16 #[structopt(alias = "mig")]
17 Migrate(MigrateOpt),
18
19 #[structopt(alias = "gen")]
20 Generate(GenerateOpt),
21}
22
23/// Group of commands for creating and dropping your database.
24#[derive(StructOpt, Debug)]
25pub struct DatabaseOpt {
26 #[structopt(subcommand)]
27 pub command: DatabaseCommand,
28}
29
30#[derive(StructOpt, Debug)]
31pub enum DatabaseCommand {
32 /// Creates the database specified in your DATABASE_URL.
33 Create {
34 /// Location of the DB, by default will be read from the DATABASE_URL env var
35 #[structopt(long, short = "D", env)]
36 database_url: String,
37 },
38
39 /// Drops the database specified in your DATABASE_URL.
40 Drop {
41 /// Automatic confirmation. Without this option, you will be prompted before dropping
42 /// your database.
43 #[structopt(short)]
44 yes: bool,
45
46 /// Location of the DB, by default will be read from the DATABASE_URL env var
47 #[structopt(long, short = "D", env)]
48 database_url: String,
49 },
50
51 /// Drops the database specified in your DATABASE_URL, re-creates it, and runs any pending migrations.
52 Reset {
53 /// Automatic confirmation. Without this option, you will be prompted before dropping
54 /// your database.
55 #[structopt(short)]
56 yes: bool,
57
58 /// Path to folder containing migrations.
59 #[structopt(long, default_value = "migrations")]
60 source: String,
61
62 /// Location of the DB, by default will be read from the DATABASE_URL env var
63 #[structopt(long, short = "D", env)]
64 database_url: String,
65 },
66
67 /// Creates the database specified in your DATABASE_URL and runs any pending migrations.
68 Setup {
69 /// Path to folder containing migrations.
70 #[structopt(long, default_value = "migrations")]
71 source: String,
72
73 /// Location of the DB, by default will be read from the DATABASE_URL env var
74 #[structopt(long, short = "D", env)]
75 database_url: String,
76 },
77}
78
79/// Group of commands for creating and running migrations.
80#[derive(StructOpt, Debug)]
81pub struct MigrateOpt {
82 /// Path to folder containing migrations.
83 #[structopt(long, default_value = "migrations")]
84 pub source: String,
85
86 #[structopt(subcommand)]
87 pub command: MigrateCommand,
88}
89/// Commands related to automatic migration generation.
90#[derive(StructOpt, Debug)]
91pub struct GenerateOpt {
92 /// Location of the DB, by default will be read from the DATABASE_URL env var
93 #[structopt(long, short = "D", env)]
94 pub database_url: String,
95 /// Path to folder containing migrations.
96 #[structopt(long, default_value = "migrations")]
97 pub source: String,
98 /// Used to filter through the sql_from_models to execute.
99 #[structopt(long)]
100 pub table: Option<String>,
101 /// Used to generate a down migrations along with up migrations.
102 #[structopt(short)]
103 pub reversible: bool,
104}
105
106impl GenerateOpt {
107 pub async fn validate(&self) -> Result<()> {
108 url::Url::parse(&self.database_url)?;
109 let migrator = Migrator::new(Path::new(&self.source)).await?;
110 for migration in migrator.iter() {
111 if migration.migration_type.is_reversible() != self.reversible {
112 Err(MigrateError::InvalidMixReversibleAndSimple)?
113 }
114 }
115
116 Ok(())
117 }
118}
119
120#[derive(StructOpt, Debug)]
121pub enum MigrateCommand {
122 /// Create a new migration with the given description,
123 /// and the current time as the version.
124 Add {
125 description: String,
126
127 /// If true, creates a pair of up and down migration files with same version
128 /// else creates a single sql file
129 #[structopt(short)]
130 reversible: bool,
131 },
132
133 /// Run all pending migrations.
134 Run {
135 /// List all the migrations to be run without applying
136 #[structopt(long)]
137 dry_run: bool,
138
139 /// Ignore applied migrations that missing in the resolved migrations
140 #[structopt(long)]
141 ignore_missing: bool,
142
143 /// Location of the DB, by default will be read from the DATABASE_URL env var
144 #[structopt(long, short = "D", env)]
145 database_url: String,
146 },
147
148 /// Revert the latest migration with a down file.
149 Revert {
150 /// List the migration to be reverted without applying
151 #[structopt(long)]
152 dry_run: bool,
153
154 /// Ignore applied migrations that missing in the resolved migrations
155 #[structopt(long)]
156 ignore_missing: bool,
157
158 /// Location of the DB, by default will be read from the DATABASE_URL env var
159 #[structopt(long, short = "D", env)]
160 database_url: String,
161 },
162
163 /// List all available migrations.
164 Info {
165 /// Location of the DB, by default will be read from the DATABASE_URL env var
166 #[structopt(long, env)]
167 database_url: String,
168 },
169
170 /// Generate a `build.rs` to trigger recompilation when a new migration is added.
171 ///
172 /// Must be run in a Cargo project root.
173 BuildScript {
174 /// Overwrite the build script if it already exists.
175 #[structopt(long)]
176 force: bool,
177 },
178}