use bytes::BytesMut; use tokio_postgres::types::{ BorrowToSql, IsNull, Type as PgType, }; #[macro_use] extern crate compact_sql; #[allow(unused)] struct ReturnRow(); impl ReturnRow { #[allow(unused)] fn from_query(_row: tokio_postgres::Row) -> Result { // Fill struct's attributes with data from the row. Ok(Self()) } } #[derive(Debug, PartialEq, Eq)] enum QueriesIds { Params3, } #[test] fn struct_ignore_rows() { pg_sql! { impl Params1 for ! { SELECT oid, relkind, FROM pg_catalog.pg_class WHERE relname = {name: String} AND relnamespace = {nsp: u32} } } let params = Params1 { name: &"123".to_string(), nsp: &11, }; let types_exp = &[PgType::NAME, PgType::OID]; let params_exp = vec![ (false, b"123" as &[u8]), (false, b"\x00\x00\x00\x0b" as &[u8]), ]; let mut buf = BytesMut::new(); let params_bin: Vec<_> = params .params() .zip(types_exp.iter()) .map(|(p, ty)| { let lbound = buf.len(); let is_null = p.borrow_to_sql().to_sql_checked(ty, &mut buf); let rbound = buf.len(); (matches!(is_null.unwrap(), IsNull::Yes), lbound..rbound) }) .collect(); let buf = buf.freeze(); let params_bin: Vec<_> = params_bin .into_iter() .map(|(is_null, r)| (is_null, &buf[r])) .collect(); assert_eq!(params_bin, params_exp); assert_eq!(Params1::PARAM_NAMES, &["name", "nsp"]); #[rustfmt::skip] assert_eq!(Params1::SQL_TEXT, concat!( "-- Params1\n", "SELECT oid,relkind FROM pg_catalog.pg_class WHERE relname=$1 AND relnamespace=$2" )); } #[test] fn single_struct() { pg_sql! { impl Params2 { SELECT oid, relnamespace, FROM pg_catalog.pg_class WHERE relname = {name: &str} AND relkind = {kind: i8} } } let params = Params2 { name: &"123".to_string(), kind: &(b'c' as i8), }; let types_exp = &[PgType::NAME, PgType::CHAR]; let params_exp = vec![(false, b"123" as &[u8]), (false, b"c" as &[u8])]; let mut buf = BytesMut::new(); let params_bin: Vec<_> = params .params() .zip(types_exp.iter()) .map(|(p, ty)| { let lbound = buf.len(); let is_null = p.borrow_to_sql().to_sql_checked(ty, &mut buf); let rbound = buf.len(); (matches!(is_null.unwrap(), IsNull::Yes), lbound..rbound) }) .collect(); let buf = buf.freeze(); let params_bin: Vec<_> = params_bin .into_iter() .map(|(is_null, r)| (is_null, &buf[r])) .collect(); assert_eq!(params_bin, params_exp); assert_eq!(Params2::PARAM_NAMES, &["name", "kind"]); #[rustfmt::skip] assert_eq!(Params2::SQL_TEXT, concat!( "-- Params2\n", "SELECT oid,relnamespace FROM pg_catalog.pg_class WHERE relname=$1 AND relkind=$2" )); } #[test] fn struct_enum_checked() { pg_sql! { impl QueriesIds::Params3 { SELECT 1 } } #[rustfmt::skip] assert_eq!(Params3::SQL_TEXT, concat!( "-- Params3\n", "SELECT 1" )); let exp: &[&str] = &[]; assert_eq!(Params3::PARAM_NAMES, exp); assert_eq!(Params3::SQL_ID, QueriesIds::Params3); }