-
Notifications
You must be signed in to change notification settings - Fork 8
/
embedded_cli_compatible.rs
95 lines (79 loc) · 3.07 KB
/
embedded_cli_compatible.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*!
This example shows functionality for behaving in a fully compatible manner with the migrant CLI tool,
while still embedding migrations in the application. During development, the CLI tool can be used
to apply migrations from files. When deployed, the application will have the migration file
contents embedded. During development, the CLI tool can use a `Migrant.toml` configuration file,
while the application can embed the settings to avoid configuration in deployed environments.
NOTE: The feature-gates are only required here so the example will compile when running
tests with and without features. In regular usage, the `cfg`s are not required since
the specified database feature should be enabled in your `Cargo.toml` entry.
This should be run with `cargo run --example embedded_cli_compatible --features d-sqlite`
*/
extern crate migrant_lib;
#[cfg(feature = "d-sqlite")]
use migrant_lib::{Config, Direction, Migrator, Settings};
#[cfg(feature = "d-sqlite")]
use std::env;
#[cfg(feature = "d-sqlite")]
fn run() -> Result<(), Box<dyn std::error::Error>> {
let path = env::current_dir()?;
let path = path.join("db/embedded_example.db");
let settings = Settings::configure_sqlite().database_path(&path)?.build()?;
let mut config = Config::with_settings(&settings);
// Initialize database migrations table
config.setup()?;
// Toggle setting so tags are validated in a cli compatible manner.
// This needs to happen before any call to `Config::use_migrations` or `Config::reload`
config.use_cli_compatible_tags(true);
// Define macro to embed cli compatible migrations
macro_rules! make_migration {
($tag:expr) => {
migrant_lib::EmbeddedMigration::with_tag($tag)
.up(include_str!(concat!(
"../migrations/managed/",
$tag,
"/up.sql"
)))
.down(include_str!(concat!(
"../migrations/managed/",
$tag,
"/down.sql"
)))
.boxed()
};
}
// Define migrations
config.use_migrations(&[
make_migration!("20180105040947_initial"),
make_migration!("20180105040952_second"),
])?;
// Reload config, ping the database for applied migrations
let config = config.reload()?;
println!("Applying migrations...");
Migrator::with_config(&config)
.all(true)
.show_output(false)
.swallow_completion(true)
.apply()?;
let config = config.reload()?;
migrant_lib::list(&config)?;
println!("\nUnapplying migrations...");
Migrator::with_config(&config)
.all(true)
.direction(Direction::Down)
.swallow_completion(true)
.apply()?;
let config = config.reload()?;
migrant_lib::list(&config)?;
Ok(())
}
#[cfg(not(feature = "d-sqlite"))]
fn run() -> Result<(), Box<dyn std::error::Error>> {
Err("d-sqlite database feature required")?;
Ok(())
}
pub fn main() {
if let Err(e) = run() {
println!("[ERROR] {}", e);
}
}