Skip to content

Commit 367f2cc

Browse files
committed
feat: teach sqlx-cli about migrate.defaults
1 parent e951d8e commit 367f2cc

File tree

4 files changed

+186
-124
lines changed

4 files changed

+186
-124
lines changed

sqlx-cli/src/lib.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::io;
2-
use std::path::{Path, PathBuf};
2+
use std::path::{PathBuf};
33
use std::time::Duration;
44

55
use anyhow::{Context, Result};
@@ -21,21 +21,14 @@ mod prepare;
2121

2222
pub use crate::opt::Opt;
2323

24-
pub use sqlx::_unstable::config;
25-
use crate::config::Config;
24+
pub use sqlx::_unstable::config::{self, Config};
2625

2726
pub async fn run(opt: Opt) -> Result<()> {
28-
let config = config_from_current_dir()?;
27+
let config = config_from_current_dir().await?;
2928

3029
match opt.command {
3130
Command::Migrate(migrate) => match migrate.command {
32-
MigrateCommand::Add {
33-
source,
34-
description,
35-
reversible,
36-
sequential,
37-
timestamp,
38-
} => migrate::add(&source, &description, reversible, sequential, timestamp).await?,
31+
MigrateCommand::Add(opts)=> migrate::add(config, opts).await?,
3932
MigrateCommand::Run {
4033
source,
4134
dry_run,

sqlx-cli/src/migrate.rs

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use crate::opt::ConnectOpts;
1+
use crate::opt::{AddMigrationOpts, ConnectOpts};
22
use anyhow::{bail, Context};
3-
use chrono::Utc;
43
use console::style;
54
use sqlx::migrate::{AppliedMigration, Migrate, MigrateError, MigrationType, Migrator};
65
use sqlx::Connection;
@@ -10,6 +9,7 @@ use std::fmt::Write;
109
use std::fs::{self, File};
1110
use std::path::Path;
1211
use std::time::Duration;
12+
use crate::config::Config;
1313

1414
fn create_file(
1515
migration_source: &str,
@@ -37,116 +37,46 @@ fn create_file(
3737
Ok(())
3838
}
3939

40-
enum MigrationOrdering {
41-
Timestamp(String),
42-
Sequential(String),
43-
}
44-
45-
impl MigrationOrdering {
46-
fn timestamp() -> MigrationOrdering {
47-
Self::Timestamp(Utc::now().format("%Y%m%d%H%M%S").to_string())
48-
}
49-
50-
fn sequential(version: i64) -> MigrationOrdering {
51-
Self::Sequential(format!("{version:04}"))
52-
}
53-
54-
fn file_prefix(&self) -> &str {
55-
match self {
56-
MigrationOrdering::Timestamp(prefix) => prefix,
57-
MigrationOrdering::Sequential(prefix) => prefix,
58-
}
59-
}
60-
61-
fn infer(sequential: bool, timestamp: bool, migrator: &Migrator) -> Self {
62-
match (timestamp, sequential) {
63-
(true, true) => panic!("Impossible to specify both timestamp and sequential mode"),
64-
(true, false) => MigrationOrdering::timestamp(),
65-
(false, true) => MigrationOrdering::sequential(
66-
migrator
67-
.iter()
68-
.last()
69-
.map_or(1, |last_migration| last_migration.version + 1),
70-
),
71-
(false, false) => {
72-
// inferring the naming scheme
73-
let migrations = migrator
74-
.iter()
75-
.filter(|migration| migration.migration_type.is_up_migration())
76-
.rev()
77-
.take(2)
78-
.collect::<Vec<_>>();
79-
if let [last, pre_last] = &migrations[..] {
80-
// there are at least two migrations, compare the last twothere's only one existing migration
81-
if last.version - pre_last.version == 1 {
82-
// their version numbers differ by 1, infer sequential
83-
MigrationOrdering::sequential(last.version + 1)
84-
} else {
85-
MigrationOrdering::timestamp()
86-
}
87-
} else if let [last] = &migrations[..] {
88-
// there is only one existing migration
89-
if last.version == 0 || last.version == 1 {
90-
// infer sequential if the version number is 0 or 1
91-
MigrationOrdering::sequential(last.version + 1)
92-
} else {
93-
MigrationOrdering::timestamp()
94-
}
95-
} else {
96-
MigrationOrdering::timestamp()
97-
}
98-
}
99-
}
100-
}
101-
}
102-
10340
pub async fn add(
104-
migration_source: &str,
105-
description: &str,
106-
reversible: bool,
107-
sequential: bool,
108-
timestamp: bool,
41+
config: &Config,
42+
opts: AddMigrationOpts,
10943
) -> anyhow::Result<()> {
110-
fs::create_dir_all(migration_source).context("Unable to create migrations directory")?;
44+
fs::create_dir_all(&opts.source).context("Unable to create migrations directory")?;
11145

112-
let migrator = Migrator::new(Path::new(migration_source)).await?;
113-
// Type of newly created migration will be the same as the first one
114-
// or reversible flag if this is the first migration
115-
let migration_type = MigrationType::infer(&migrator, reversible);
46+
let migrator = Migrator::new(opts.source.as_ref()).await?;
11647

117-
let ordering = MigrationOrdering::infer(sequential, timestamp, &migrator);
118-
let file_prefix = ordering.file_prefix();
48+
let version_prefix = opts.version_prefix(config, &migrator);
11949

120-
if migration_type.is_reversible() {
50+
if opts.reversible(config, &migrator) {
12151
create_file(
122-
migration_source,
123-
file_prefix,
124-
description,
52+
&opts.source,
53+
&version_prefix,
54+
&opts.description,
12555
MigrationType::ReversibleUp,
12656
)?;
12757
create_file(
128-
migration_source,
129-
file_prefix,
130-
description,
58+
&opts.source,
59+
&version_prefix,
60+
&opts.description,
13161
MigrationType::ReversibleDown,
13262
)?;
13363
} else {
13464
create_file(
135-
migration_source,
136-
file_prefix,
137-
description,
65+
&opts.source,
66+
&version_prefix,
67+
&opts.description,
13868
MigrationType::Simple,
13969
)?;
14070
}
14171

14272
// if the migrations directory is empty
143-
let has_existing_migrations = fs::read_dir(migration_source)
73+
let has_existing_migrations = fs::read_dir(&opts.source)
14474
.map(|mut dir| dir.next().is_some())
14575
.unwrap_or(false);
14676

14777
if !has_existing_migrations {
148-
let quoted_source = if migration_source != "migrations" {
149-
format!("{migration_source:?}")
78+
let quoted_source = if *opts.source != "migrations" {
79+
format!("{:?}", *opts.source)
15080
} else {
15181
"".to_string()
15282
};

0 commit comments

Comments
 (0)