Skip to main content
edited body
Source Link
toolic
  • 16.4k
  • 6
  • 29
  • 221

I implemented the Repository Pattern as follow, there. There is allota lot of room for improvement, and I will be glad to improve it more.

I implemented the Repository Pattern as follow, there is allot of room for improvement, and I will be glad to improve it more.

I implemented the Repository Pattern as follow. There is a lot of room for improvement, and I will be glad to improve it more.

Source Link
HMK
  • 11
  • 2

I implemented the Repository Pattern as follow, there is allot of room for improvement, and I will be glad to improve it more.

use sqlx::{pool::PoolConnection, Postgres, Error};

use crate::models::application::model::Model;

#[async_trait::async_trait]
pub trait Repository<TEntity>
where
    TEntity: Model,
{
    /// get all entities
    async fn get_all(&self, connection: PoolConnection<Postgres>) -> Result<Vec<TEntity>, Error>;

    /// get a single entity by id
    async fn get_by_id(&self, connection: PoolConnection<Postgres>, id: &String) -> Result<TEntity, String>;

    /// add an entity to the database
    async fn add(&mut self, connection: PoolConnection<Postgres>, entity: &TEntity) -> Result<(), String>;

    /// update an entity
    async fn update(&mut self, connection: PoolConnection<Postgres>, entity: &TEntity) -> Result<(), String>;

    /// delete an entity by its id
    async fn delete(&mut self, connection: PoolConnection<Postgres>, id: &String) -> Result<(), String>;
}

Now Implementation

pub use sqlx::{
    pool::PoolConnection,
    postgres::{PgArguments, PgPoolOptions, PgRow},
    Arguments, Error, PgPool, Postgres, Row,
};

use crate::handlers::db_repository::Repository;
use crate::models::application::model::Model;
use crate::models::application::roles::users::User;

pub struct UserRepository { }

#[async_trait::async_trait]
impl Repository<User> for UserRepository {
    async fn get_all(&self, mut connection: PoolConnection<Postgres>) -> Result<Vec<User>, Error> {
        let result = sqlx::query("SELECT \"UserId\", \"Username\", \"DisplayName\", \"Language\", \"Password\", \"Salt\", \"StatusId\" FROM \"Role\".\"User\"")
            .map(|row: PgRow| User::from_row(&row))
            .fetch_all(&mut *connection)
            .await?;

        Ok(result)
    }

    async fn get_by_id(
        &self,
        mut connection: PoolConnection<Postgres>,
        id: &String,
    ) -> Result<User, String> {
        let mut args = PgArguments::default();
        args.add(id);

        let result = sqlx::query_with(
            "SELECT \"UserId\", \"Username\", \"DisplayName\", \"Language\", \"Password\", \"Salt\", \"StatusId\" FROM \"Role\".\"User\" WHERE \"UserId\"='$1'",
            args,
        )
        .map(|row: sqlx::postgres::PgRow| User::from_row(&row))
        .fetch_one(&mut *connection)
        .await;

        Ok(result.unwrap())
    }

    async fn add(
        &mut self,
        mut connection: PoolConnection<Postgres>,
        entity: &User,
    ) -> Result<(), String> {
        let mut args = PgArguments::default();
        args.add(entity.user_id.clone());
        args.add(entity.username.clone());
        args.add(entity.display_name.clone());
        args.add(entity.language.clone());
        args.add(entity.password.clone());
        args.add(entity.salt.clone());
        args.add(entity.status_id.clone());

        let result = sqlx::query_with("INSERT INTO \"User\" (\"UserId\", \"Username\", \"DisplayName\", \"Language\", \"Password\", \"Salt\", \"StatusId\") VALUES ($1, $2, $3, $4, $5, $6, $7);", args)
        .execute(&mut *connection)
        .await;

        match result {
            Ok(_) => Ok(()),
            Err(err) => Err(err.to_string()),
        }
    }

    async fn update(
        &mut self,
        mut connection: PoolConnection<Postgres>,
        entity: &User,
    ) -> Result<(), String> {
        let mut args = PgArguments::default();
        args.add(entity.user_id.clone());
        args.add(entity.username.clone());
        args.add(entity.display_name.clone());
        args.add(entity.language.clone());
        args.add(entity.password.clone());
        args.add(entity.salt.clone());
        args.add(entity.status_id.clone());

        let result = sqlx::query_with("UPDATE \"User\" SET \"Username\" = $2, \"DisplayName\" = $3, \"Language\" = $4, \"Password\" = $5, \"Salt\" = $6, \"StatusId\" = $7 WHERE \"UserId\" = $1;", args)
        .execute(&mut *connection)
        .await;

        match result {
            Ok(_) => Ok(()),
            Err(err) => Err(err.to_string()),
        }
    }

    async fn delete(
        &mut self,
        mut connection: PoolConnection<Postgres>,
        id: &String,
    ) -> Result<(), String> {
        let mut args = PgArguments::default();
        args.add(id);

        let result = sqlx::query_with("DELETE FROM \"User\" WHERE \"UserId\" = $1;", args)
            .execute(&mut *connection)
            .await;

        match result {
            Ok(_) => Ok(()),
            Err(err) => Err(err.to_string()),
        }
    }
}