#![allow(dead_code)]
use std::sync::OnceLock;
use reliar_core::{MessageId, MessageType};
use reliar_inbox::{InboxHandler, InboxMessage, InboxScope, InboxStore};
use reliar_store_postgres::PostgresInboxStore;
use sqlx::{Postgres, Transaction};
pub(crate) fn message_type() -> &'static MessageType {
static MESSAGE_TYPE: OnceLock<MessageType> = OnceLock::new();
MESSAGE_TYPE.get_or_init(|| MessageType::new("orders.created", 1))
}
pub(crate) fn message(id: MessageId) -> InboxMessage<'static> {
InboxMessage::new(id, message_type())
}
pub(crate) async fn create_business_table(pool: &sqlx::PgPool) {
sqlx::query("CREATE TABLE business_events (id bigserial PRIMARY KEY, value bigint NOT NULL)")
.execute(pool)
.await
.unwrap();
}
pub(crate) async fn business_row_count(pool: &sqlx::PgPool) -> i64 {
sqlx::query_scalar("SELECT count(*) FROM business_events")
.fetch_one(pool)
.await
.unwrap()
}
pub(crate) struct InsertBusinessRow {
pub(crate) value: i64,
}
impl InboxHandler<Transaction<'_, Postgres>> for InsertBusinessRow {
type Output = i64;
type Error = sqlx::Error;
async fn handle(&self, tx: &mut Transaction<'_, Postgres>) -> Result<i64, sqlx::Error> {
sqlx::query("INSERT INTO business_events (value) VALUES ($1)")
.bind(self.value)
.execute(&mut **tx)
.await?;
Ok(self.value)
}
}
pub(crate) struct InsertThenFail {
pub(crate) value: i64,
}
#[derive(Debug)]
pub(crate) struct HandlerFailed;
impl std::fmt::Display for HandlerFailed {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "handler failed, by design")
}
}
impl std::error::Error for HandlerFailed {}
impl InboxHandler<Transaction<'_, Postgres>> for InsertThenFail {
type Output = ();
type Error = HandlerFailed;
async fn handle(&self, tx: &mut Transaction<'_, Postgres>) -> Result<(), HandlerFailed> {
sqlx::query("INSERT INTO business_events (value) VALUES ($1)")
.bind(self.value)
.execute(&mut **tx)
.await
.unwrap();
Err(HandlerFailed)
}
}
pub(crate) struct SelfCompletingHandler<'a> {
pub(crate) store: &'a PostgresInboxStore,
pub(crate) scope: InboxScope,
pub(crate) id: MessageId,
}
impl InboxHandler<Transaction<'_, Postgres>> for SelfCompletingHandler<'_> {
type Output = ();
type Error = std::convert::Infallible;
#[allow(
clippy::expect_used,
reason = "a fixture helper's own precondition, not a #[test] body"
)]
async fn handle(
&self,
tx: &mut Transaction<'_, Postgres>,
) -> Result<(), std::convert::Infallible> {
self.store
.complete(tx, &self.scope, self.id)
.await
.expect("the row is freshly claimed, so this store-side complete must succeed");
Ok(())
}
}
pub(crate) struct NoopHandler;
impl InboxHandler<Transaction<'_, Postgres>> for NoopHandler {
type Output = ();
type Error = std::convert::Infallible;
fn handle(
&self,
_tx: &mut Transaction<'_, Postgres>,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
std::future::ready(Ok(()))
}
}