mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +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:
145
Cargo.lock
generated
145
Cargo.lock
generated
@ -384,12 +384,55 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.81"
|
||||
@ -1909,8 +1952,10 @@ version = "4.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1940,6 +1985,12 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "common_enums"
|
||||
version = "0.1.0"
|
||||
@ -2016,7 +2067,7 @@ dependencies = [
|
||||
"rust-ini",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"toml 0.8.12",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
@ -2029,7 +2080,7 @@ dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"toml 0.8.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2039,7 +2090,7 @@ dependencies = [
|
||||
"api_models",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"toml",
|
||||
"toml 0.8.12",
|
||||
"utoipa",
|
||||
]
|
||||
|
||||
@ -2588,9 +2639,9 @@ checksum = "b6e854126756c496b8c81dec88f9a706b15b875c5849d4097a3854476b9fdf94"
|
||||
|
||||
[[package]]
|
||||
name = "diesel"
|
||||
version = "2.1.5"
|
||||
version = "2.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03fc05c17098f21b89bc7d98fe1dd3cce2c11c2ad8e145f2a44fe08ed28eb559"
|
||||
checksum = "ff236accb9a5069572099f0b350a92e9560e8e63a9b8d546162f4a5e03026bb2"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
@ -2604,9 +2655,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "diesel_derives"
|
||||
version = "2.1.3"
|
||||
version = "2.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d02eecb814ae714ffe61ddc2db2dd03e6c49a42e269b5001355500d431cce0c"
|
||||
checksum = "14701062d6bed917b5c7103bdffaee1e4609279e240488ad24e7bd979ca6866c"
|
||||
dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"proc-macro2",
|
||||
@ -2614,6 +2665,17 @@ dependencies = [
|
||||
"syn 2.0.57",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_migrations"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac"
|
||||
dependencies = [
|
||||
"diesel",
|
||||
"migrations_internals",
|
||||
"migrations_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diesel_models"
|
||||
version = "0.1.0"
|
||||
@ -3584,6 +3646,17 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hsdev"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"diesel",
|
||||
"diesel_migrations",
|
||||
"serde",
|
||||
"toml 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.12"
|
||||
@ -4020,6 +4093,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "iso_country"
|
||||
version = "0.1.4"
|
||||
@ -4396,6 +4475,27 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_internals"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"toml 0.7.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "migrations_macros"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08"
|
||||
dependencies = [
|
||||
"migrations_internals",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mimalloc"
|
||||
version = "0.1.39"
|
||||
@ -7370,7 +7470,7 @@ dependencies = [
|
||||
"thirtyfour",
|
||||
"time",
|
||||
"tokio 1.37.0",
|
||||
"toml",
|
||||
"toml 0.8.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7798,6 +7898,27 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.19.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
@ -7827,6 +7948,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
@ -8243,6 +8366,12 @@ version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "110352d4e9076c67839003c7788d8604e24dcded13e0b375af3efaa8cf468517"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "utoipa"
|
||||
version = "4.2.0"
|
||||
|
||||
16
crates/hsdev/Cargo.toml
Normal file
16
crates/hsdev/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "hsdev"
|
||||
version = "0.1.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
description = "A simple diesel postgres migrator that uses TOML files"
|
||||
repository = "https://github.com/juspay/hyperswitch.git"
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
diesel = { version = "2.1.6", features = ["postgres"] }
|
||||
diesel_migrations = "2.1.0"
|
||||
toml = "0.5"
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
24
crates/hsdev/README.md
Normal file
24
crates/hsdev/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# HSDEV
|
||||
|
||||
`hsdev` is a simple diesel Postgres migration tool. It is designed to simply running a Postgres database migration with diesel.
|
||||
|
||||
## Installing hsdev
|
||||
`hsdev` can be installed using `cargo`
|
||||
```shell
|
||||
cargo install --force --path crates/hsdev
|
||||
```
|
||||
|
||||
## Using hsdev
|
||||
Using `hsdev` is simple. All you need to do is run the following command.
|
||||
```shell
|
||||
hsdev --toml-file [path/to/TOML/file]
|
||||
```
|
||||
|
||||
provide `hsdev` with a TOML file containing the following keys:
|
||||
```toml
|
||||
username = "your_username"
|
||||
password = "your_password"
|
||||
dbname = "your_db_name"
|
||||
```
|
||||
|
||||
Simply run the command and let `hsdev` handle the rest.
|
||||
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