Extract postgres todo repo struct

This commit is contained in:
Matt Paul 2020-11-18 14:50:51 +00:00 committed by Ryan Leckey
parent 012d72464e
commit 6ac5d2269e
No known key found for this signature in database
GPG Key ID: F8AA68C235AB08C9

View File

@ -1,6 +1,6 @@
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use sqlx::Done; use sqlx::Done;
use std::env; use std::{env, sync::Arc};
use structopt::StructOpt; use structopt::StructOpt;
#[derive(StructOpt)] #[derive(StructOpt)]
@ -19,16 +19,21 @@ enum Command {
#[paw::main] #[paw::main]
async fn main(args: Args) -> anyhow::Result<()> { async fn main(args: Args) -> anyhow::Result<()> {
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?; let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
let todo_repo = PostgresTodoRepo::new(pool);
handle_command(args, todo_repo).await
}
async fn handle_command(args: Args, todo_repo: PostgresTodoRepo) -> anyhow::Result<()> {
match args.cmd { match args.cmd {
Some(Command::Add { description }) => { Some(Command::Add { description }) => {
println!("Adding new todo with description '{}'", &description); println!("Adding new todo with description '{}'", &description);
let todo_id = add_todo(&pool, description).await?; let todo_id = todo_repo.add_todo(description).await?;
println!("Added new todo with id {}", todo_id); println!("Added new todo with id {}", todo_id);
} }
Some(Command::Done { id }) => { Some(Command::Done { id }) => {
println!("Marking todo {} as done", id); println!("Marking todo {} as done", id);
if complete_todo(&pool, id).await? { if todo_repo.complete_todo(id).await? {
println!("Todo {} is marked as done", id); println!("Todo {} is marked as done", id);
} else { } else {
println!("Invalid id {}", id); println!("Invalid id {}", id);
@ -36,14 +41,25 @@ async fn main(args: Args) -> anyhow::Result<()> {
} }
None => { None => {
println!("Printing list of all todos"); println!("Printing list of all todos");
list_todos(&pool).await?; todo_repo.list_todos().await?;
} }
} }
Ok(()) Ok(())
} }
async fn add_todo(pool: &PgPool, description: String) -> anyhow::Result<i64> { struct PostgresTodoRepo {
pg_pool: Arc<PgPool>,
}
impl PostgresTodoRepo {
fn new(pg_pool: PgPool) -> Self {
Self {
pg_pool: Arc::new(pg_pool),
}
}
async fn add_todo(&self, description: String) -> anyhow::Result<i64> {
let rec = sqlx::query!( let rec = sqlx::query!(
r#" r#"
INSERT INTO todos ( description ) INSERT INTO todos ( description )
@ -52,13 +68,13 @@ RETURNING id
"#, "#,
description description
) )
.fetch_one(pool) .fetch_one(&*self.pg_pool)
.await?; .await?;
Ok(rec.id) Ok(rec.id)
} }
async fn complete_todo(pool: &PgPool, id: i64) -> anyhow::Result<bool> { async fn complete_todo(&self, id: i64) -> anyhow::Result<bool> {
let rows_affected = sqlx::query!( let rows_affected = sqlx::query!(
r#" r#"
UPDATE todos UPDATE todos
@ -67,14 +83,14 @@ WHERE id = $1
"#, "#,
id id
) )
.execute(pool) .execute(&*self.pg_pool)
.await? .await?
.rows_affected(); .rows_affected();
Ok(rows_affected > 0) Ok(rows_affected > 0)
} }
async fn list_todos(pool: &PgPool) -> anyhow::Result<()> { async fn list_todos(&self) -> anyhow::Result<()> {
let recs = sqlx::query!( let recs = sqlx::query!(
r#" r#"
SELECT id, description, done SELECT id, description, done
@ -82,7 +98,7 @@ FROM todos
ORDER BY id ORDER BY id
"# "#
) )
.fetch_all(pool) .fetch_all(&*self.pg_pool)
.await?; .await?;
for rec in recs { for rec in recs {
@ -95,4 +111,5 @@ ORDER BY id
} }
Ok(()) Ok(())
}
} }