mod entities;
mod helpers;
use entities::user::*;
use es_entity::{DbOp, *};
#[derive(EsRepo, Debug)]
#[es_repo(
entity = "User",
in_op_only,
columns(name(ty = "String", list_by, list_for))
)]
pub struct Users {}
fn new_user(name: &str) -> NewUser {
NewUser::builder()
.id(UserId::new())
.name(name.to_string())
.build()
.expect("failed to build user")
}
#[tokio::test]
async fn pool_less_repo_writes_and_reads_through_a_passed_op() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let users = Users {};
let mut op = DbOp::init(&pool).await?;
let mut user = users
.create_in_op(&mut op, new_user("in_op_only create"))
.await?;
let id = user.id;
op.commit().await?;
let mut op = DbOp::init(&pool).await?;
let _ = user.update_name("in_op_only updated");
users.update_in_op(&mut op, &mut user).await?;
op.commit().await?;
let found = users.find_by_id_in_op(&pool, id).await?;
assert_eq!(found.name, "in_op_only updated");
let mut op = DbOp::init(&pool).await?;
let mut uncommitted = users.create_in_op(&mut op, new_user("uncommitted")).await?;
let uncommitted_id = uncommitted.id;
let seen = users.find_by_id_in_op(&mut op, uncommitted_id).await?;
assert_eq!(seen.name, "uncommitted");
let _ = uncommitted.update_name("still uncommitted");
users.update_in_op(&mut op, &mut uncommitted).await?;
op.commit().await?;
Ok(())
}
#[tokio::test]
async fn pool_less_repo_serves_every_read_family_in_op() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let users = Users {};
let unique = format!("in_op_only_reads_{}", UserId::new());
let mut op = DbOp::init(&pool).await?;
let user = users.create_in_op(&mut op, new_user(&unique)).await?;
op.commit().await?;
let all: std::collections::HashMap<UserId, User> =
users.find_all_in_op(&pool, &[user.id]).await?;
assert!(all.contains_key(&user.id));
let by_name = users
.list_by_name_in_op(
&pool,
PaginatedQueryArgs {
first: 10,
after: None,
},
ListDirection::Descending,
)
.await?;
assert!(!by_name.entities.is_empty());
let for_name = users
.list_for_name_by_id_in_op(
&pool,
unique.clone(),
PaginatedQueryArgs {
first: 10,
after: None,
},
ListDirection::Ascending,
)
.await?;
assert_eq!(for_name.entities.len(), 1);
assert_eq!(for_name.entities[0].id, user.id);
let filtered = users
.list_for_filters_in_op(
&pool,
UserFilters {
name: Some(unique.clone()),
},
Sort {
by: UserSortBy::Id,
direction: ListDirection::Ascending,
},
PaginatedQueryArgs {
first: 10,
after: None,
},
)
.await?;
assert_eq!(filtered.entities.len(), 1);
assert_eq!(filtered.entities[0].id, user.id);
let unfiltered = users
.list_for_filters_in_op(
&pool,
UserFilters::default(),
Sort {
by: UserSortBy::Id,
direction: ListDirection::Descending,
},
PaginatedQueryArgs {
first: 10,
after: None,
},
)
.await?;
assert!(!unfiltered.entities.is_empty());
Ok(())
}
mod with_pool {
use super::{entities::user::*, helpers, new_user};
use es_entity::*;
use sqlx::PgPool;
#[derive(EsRepo, Debug)]
#[es_repo(entity = "User", in_op_only, columns(name(ty = "String")))]
pub struct Users {
pool: PgPool,
}
#[tokio::test]
async fn in_op_only_repo_with_a_pool_can_still_begin_its_own_op() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let users = Users { pool: pool.clone() };
let mut op = users.begin_op().await?;
let user = users
.create_in_op(&mut op, new_user("in_op_only with pool"))
.await?;
op.commit().await?;
let found = users.find_by_id_in_op(users.pool(), user.id).await?;
assert_eq!(found.name, "in_op_only with pool");
Ok(())
}
}