mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat: add hsdev binary to run migrations (#4877)
Co-authored-by: James Motherwell <motherwell.james@student.greenriver.edu> Co-authored-by: James M <122129564+JamesM25@users.noreply.github.com>
This commit is contained in:
26
crates/hsdev/src/input_file.rs
Normal file
26
crates/hsdev/src/input_file.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use std::string::String;
|
||||
|
||||
use serde::Deserialize;
|
||||
use toml::Value;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct InputData {
|
||||
username: String,
|
||||
password: String,
|
||||
dbname: String,
|
||||
host: String,
|
||||
port: u16,
|
||||
}
|
||||
|
||||
impl InputData {
|
||||
pub fn read(db_table: &Value) -> Result<Self, toml::de::Error> {
|
||||
db_table.clone().try_into()
|
||||
}
|
||||
|
||||
pub fn postgres_url(&self) -> String {
|
||||
format!(
|
||||
"postgres://{}:{}@{}:{}/{}",
|
||||
self.username, self.password, self.host, self.port, self.dbname
|
||||
)
|
||||
}
|
||||
}
|
||||
139
crates/hsdev/src/main.rs
Normal file
139
crates/hsdev/src/main.rs
Normal file
@ -0,0 +1,139 @@
|
||||
use clap::{Parser, ValueHint};
|
||||
use diesel::{pg::PgConnection, Connection};
|
||||
use diesel_migrations::{FileBasedMigrations, HarnessWithOutput, MigrationHarness};
|
||||
use toml::Value;
|
||||
|
||||
mod input_file;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
#[arg(short, long, value_hint = ValueHint::FilePath)]
|
||||
toml_file: std::path::PathBuf,
|
||||
|
||||
#[arg(long, default_value_t = String::from(""))]
|
||||
toml_table: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let toml_file = &args.toml_file;
|
||||
let table_name = &args.toml_table;
|
||||
let toml_contents = match std::fs::read_to_string(toml_file) {
|
||||
Ok(contents) => contents,
|
||||
Err(e) => {
|
||||
eprintln!("Error reading TOML file: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let toml_data: Value = match toml_contents.parse() {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
eprintln!("Error parsing TOML file: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let table = get_toml_table(table_name, &toml_data);
|
||||
|
||||
let input = match input_file::InputData::read(table) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
eprintln!("Error loading TOML file: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let db_url = input.postgres_url();
|
||||
|
||||
println!("Attempting to connect to {}", db_url);
|
||||
|
||||
let mut conn = match PgConnection::establish(&db_url) {
|
||||
Ok(value) => value,
|
||||
Err(_) => {
|
||||
eprintln!("Unable to establish database connection");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let migrations = match FileBasedMigrations::find_migrations_directory() {
|
||||
Ok(value) => value,
|
||||
Err(_) => {
|
||||
eprintln!("Could not find migrations directory");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut harness = HarnessWithOutput::write_to_stdout(&mut conn);
|
||||
|
||||
match harness.run_pending_migrations(migrations) {
|
||||
Ok(_) => println!("Successfully ran migrations"),
|
||||
Err(_) => eprintln!("Couldn't run migrations"),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_toml_table<'a>(table_name: &'a str, toml_data: &'a Value) -> &'a Value {
|
||||
if !table_name.is_empty() {
|
||||
match toml_data.get(table_name) {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
eprintln!("Unable to find toml table: \"{}\"", &table_name);
|
||||
std::process::abort()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toml_data
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use toml::Value;
|
||||
|
||||
use crate::{get_toml_table, input_file::InputData};
|
||||
|
||||
#[test]
|
||||
fn test_input_file() {
|
||||
let toml_str = r#"username = "db_user"
|
||||
password = "db_pass"
|
||||
dbname = "db_name"
|
||||
host = "localhost"
|
||||
port = 5432"#;
|
||||
|
||||
let toml_value = Value::from_str(toml_str);
|
||||
assert!(toml_value.is_ok());
|
||||
let toml_value = toml_value.unwrap();
|
||||
|
||||
let toml_table = InputData::read(&toml_value);
|
||||
assert!(toml_table.is_ok());
|
||||
let toml_table = toml_table.unwrap();
|
||||
|
||||
let db_url = toml_table.postgres_url();
|
||||
assert_eq!("postgres://db_user:db_pass@localhost:5432/db_name", db_url);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_given_toml() {
|
||||
let toml_str_table = r#"[database]
|
||||
username = "db_user"
|
||||
password = "db_pass"
|
||||
dbname = "db_name"
|
||||
host = "localhost"
|
||||
port = 5432"#;
|
||||
|
||||
let table_name = "database";
|
||||
let toml_value = Value::from_str(toml_str_table).unwrap();
|
||||
let table = get_toml_table(table_name, &toml_value);
|
||||
|
||||
assert!(table.is_table());
|
||||
|
||||
let table_name = "";
|
||||
let table = get_toml_table(table_name, &toml_value);
|
||||
assert!(table.is_table());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user