use sqlx::PgPool;
use sqlx::postgres::PgPoolOptions;
use testcontainers::ContainerAsync;
use testcontainers_modules::postgres::Postgres;
use testcontainers_modules::testcontainers::runners::AsyncRunner;
const SCHEMA_DDL: &str = r#"
CREATE TABLE outbound_queue (
id BIGSERIAL PRIMARY KEY,
sender TEXT NOT NULL,
recipient TEXT NOT NULL,
domain TEXT NOT NULL,
message_data BYTEA NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
attempts INTEGER NOT NULL DEFAULT 0,
max_attempts INTEGER NOT NULL DEFAULT 8,
next_retry BIGINT NOT NULL,
last_error TEXT,
message_id TEXT,
created_at BIGINT NOT NULL,
updated_at BIGINT NOT NULL,
is_forwarded BOOLEAN NOT NULL DEFAULT false
);
CREATE INDEX idx_queue_pending ON outbound_queue(status, next_retry)
WHERE status = 'pending';
CREATE TABLE suppression_list (
id BIGSERIAL PRIMARY KEY,
email TEXT NOT NULL,
reason TEXT NOT NULL DEFAULT '',
bounce_type TEXT NOT NULL DEFAULT 'hard',
smtp_code INTEGER,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX idx_suppression_email ON suppression_list (email);
CREATE INDEX idx_suppression_created ON suppression_list (created_at DESC);
"#;
pub async fn start_pg() -> (ContainerAsync<Postgres>, PgPool) {
let container = Postgres::default()
.start()
.await
.expect("start postgres container");
let host = container
.get_host()
.await
.expect("get container host")
.to_string();
let port = container
.get_host_port_ipv4(5432)
.await
.expect("get container port");
let url = format!("postgres://postgres:postgres@{host}:{port}/postgres");
let pool = PgPoolOptions::new()
.max_connections(8)
.connect(&url)
.await
.expect("connect to postgres");
sqlx::raw_sql(SCHEMA_DDL)
.execute(&pool)
.await
.expect("apply schema DDL");
(container, pool)
}