-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
kirkbyers
committed
Apr 14, 2024
1 parent
90a5d88
commit 82400b8
Showing
5 changed files
with
77 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SELECT Count(*) from jobs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SELECT Count(*) from jobs; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use std::{env, fs}; | ||
|
||
use zero2prod::{db, jobs}; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let args: Vec<String> = env::args().collect(); | ||
assert!(args.len() > 1); | ||
|
||
let db = db::start_db().await.unwrap(); | ||
let conn = db.connect().unwrap(); | ||
|
||
let current_dir = env::current_dir().unwrap(); | ||
for file_path in &args[1..] { | ||
let mut migration_files: Vec<String> = vec![]; | ||
let path_res = current_dir.join(file_path); | ||
|
||
if path_res.is_dir() { | ||
for entry in fs::read_dir(path_res).unwrap() { | ||
let entry = entry.unwrap(); | ||
let entry_path = entry.path(); | ||
if entry_path.is_file() { | ||
migration_files.push(entry_path.to_str().unwrap().to_string()) | ||
} | ||
} | ||
} else { | ||
migration_files.push(path_res.to_str().unwrap().to_string()); | ||
} | ||
|
||
for migration_file in migration_files { | ||
let file_content = fs::read_to_string(&migration_file).unwrap(); | ||
jobs::migrations::run_up(&conn, &migration_file, &file_content) | ||
.await | ||
.unwrap(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,72 @@ | ||
use libsql::{Connection, Error, Rows}; | ||
use libsql::{Connection, Error}; | ||
|
||
const MIGRATION_TABLE_NAME: &str = "migrations"; | ||
|
||
/// Sets up the migration table if it doesn't exist. | ||
/// | ||
/// | ||
/// # Arguments | ||
/// | ||
/// | ||
/// * `conn` - A reference to the database connection. | ||
/// | ||
/// | ||
/// # Returns | ||
/// | ||
/// | ||
/// Returns `Ok(())` if the setup is successful, otherwise returns an `Error`. | ||
async fn setup(conn: &Connection) -> Result<(), Error> { | ||
let table_exists_query = format!("SELECT to_regclass('{}');", MIGRATION_TABLE_NAME); | ||
let mut rows: Rows = conn.query(&table_exists_query, ()).await?; | ||
match rows.next().await? { | ||
Some(_) => (), | ||
None => { | ||
conn.query( | ||
&format!( | ||
r#" | ||
CREATE TABLE IF NOT EXISTS {} ( | ||
id uuid NOT NULL PRIMARY KEY, | ||
title TEXT NOT NULL, | ||
created_at TEXT | ||
); | ||
"#, | ||
MIGRATION_TABLE_NAME | ||
), | ||
(), | ||
) | ||
.await?; | ||
} | ||
}; | ||
conn.query( | ||
&format!( | ||
r#" | ||
CREATE TABLE IF NOT EXISTS {} ( | ||
id uuid NOT NULL PRIMARY KEY, | ||
title TEXT NOT NULL, | ||
created_at TEXT | ||
); | ||
"#, | ||
MIGRATION_TABLE_NAME | ||
), | ||
(), | ||
) | ||
.await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Runs an "up" migration. Errors if migration with same title has been previously | ||
/// Runs an "up" migration. Skip if migration with same title has been previously | ||
/// ran. | ||
/// | ||
/// | ||
/// # Arguments | ||
/// | ||
/// | ||
/// * `conn` - A reference to the database connection. | ||
/// * `title` - The title of the migration. | ||
/// * `migration_sql` - The SQL statement for the migration. | ||
/// | ||
/// | ||
/// # Returns | ||
/// | ||
/// | ||
/// Returns `Ok(())` if the migration is successful, otherwise returns an `Error`. | ||
pub async fn run_up(conn: &Connection, title: &str, migration_sql: &str) -> Result<(), Error> { | ||
setup(conn).await?; | ||
let existing_migration_query = format!( | ||
"SELECT id FROM {} WHERE title = '{}';", | ||
MIGRATION_TABLE_NAME, | ||
title | ||
MIGRATION_TABLE_NAME, title | ||
); | ||
let mut existing_migration_rows = conn.query(&existing_migration_query, ()).await?; | ||
match existing_migration_rows.next().await? { | ||
Some(_) => Err(Error::Misuse("Migration previously ran".to_string())), | ||
Some(_) => { | ||
println!("Skipping Migration '{}'", title); | ||
Ok(()) | ||
} | ||
None => { | ||
println!("Running Migration '{}'", title); | ||
conn.query(migration_sql, ()).await?; | ||
|
||
let now = chrono::Utc::now().to_rfc3339(); | ||
let uuid = uuid::Uuid::new_v4(); | ||
let insert_ran_migration = format!( | ||
"INSERT INTO {} (id, title, created_at) ('{}', '{}', '{}')", | ||
MIGRATION_TABLE_NAME, | ||
uuid, | ||
title, | ||
now | ||
"INSERT INTO {} (id, title, created_at) VALUES ('{}', '{}', '{}');", | ||
MIGRATION_TABLE_NAME, uuid, title, now | ||
); | ||
conn.query(&insert_ran_migration, ()).await?; | ||
println!("Ran Migration '{}' Successfuly", title); | ||
Ok(()) | ||
} | ||
} | ||
} | ||
} |