#![cfg(test)]
use std::time::Duration;
use prax_orm::{Model, PraxClient, client};
use prax_postgres::{PgEngine, PgPool, PgPoolBuilder};
use prax_query::raw::Sql;
use prax_query::types::Select;
#[derive(Debug, Model)]
#[prax(table = "select_pg_users")]
struct User {
#[prax(id, auto)]
id: i32,
#[prax(unique)]
email: String,
name: Option<String>,
}
client!(User);
fn postgres_url() -> Option<String> {
if std::env::var("PRAX_E2E").ok().as_deref() != Some("1") {
return None;
}
Some(
std::env::var("POSTGRES_URL").unwrap_or_else(|_| {
"postgres://prax:prax_test_password@localhost:5432/prax_test".into()
}),
)
}
async fn setup() -> Option<PraxClient<PgEngine>> {
let url = postgres_url()?;
let pool: PgPool = PgPoolBuilder::new()
.url(url)
.max_connections(4)
.connection_timeout(Duration::from_secs(10))
.build()
.await
.expect("connect to postgres");
let conn = pool.get().await.expect("acquire conn");
conn.batch_execute(
"BEGIN;
SELECT pg_advisory_xact_lock(0x73656c5f706700);
CREATE TABLE IF NOT EXISTS select_pg_users (
id SERIAL PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
name TEXT
);
TRUNCATE TABLE select_pg_users RESTART IDENTITY;
COMMIT",
)
.await
.expect("create select_pg_users");
drop(conn);
Some(PraxClient::new(PgEngine::new(pool)))
}
#[tokio::test]
#[ignore = "requires docker-compose postgres (PRAX_E2E=1)"]
async fn select_narrows_sql_column_list() {
let Some(c) = setup().await else {
eprintln!("skipping: PRAX_E2E not set");
return;
};
c.execute_raw(
Sql::new("INSERT INTO select_pg_users (email, name) VALUES (")
.bind("a@example.com")
.push(", ")
.bind("A")
.push("), (")
.bind("b@example.com")
.push(", ")
.bind("B")
.push(")"),
)
.await
.expect("seed");
let narrow_op = c.user().find_many().select(Select::fields(["id", "email"]));
let (narrow_sql, _) = narrow_op.build_sql(&prax_query::dialect::Postgres);
assert!(
narrow_sql.contains("SELECT id, email FROM select_pg_users")
&& !narrow_sql.contains("SELECT *"),
"expected narrow SELECT list, got: {narrow_sql}"
);
let users = c
.user()
.find_many()
.select(Select::fields(["id", "email", "name"]))
.exec()
.await
.expect("find_many with explicit projection");
assert_eq!(users.len(), 2, "expected both seeded rows");
let full_op = c
.user()
.find_many()
.select(Select::fields(["id", "email", "name"]));
let (full_sql, _) = full_op.build_sql(&prax_query::dialect::Postgres);
assert!(
full_sql.contains("SELECT id, email, name FROM select_pg_users"),
"expected explicit three-column SELECT, got: {full_sql}"
);
let default_op = c.user().find_many();
let (default_sql, _) = default_op.build_sql(&prax_query::dialect::Postgres);
assert!(
default_sql.contains("SELECT * FROM select_pg_users"),
"expected default SELECT *, got: {default_sql}"
);
}