Skip to content

Commit

Permalink
Add test for named schema
Browse files Browse the repository at this point in the history
  • Loading branch information
Virgiel committed May 22, 2023
1 parent b0ea64a commit 8940433
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 4 deletions.
188 changes: 188 additions & 0 deletions test_codegen/codegen/src/queries/stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,57 @@ pub mod sync {
Ok(it)
}
}
pub struct SchemaNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> {
client: &'a mut C,
params: [&'a (dyn postgres_types::ToSql + Sync); N],
stmt: &'a mut crate::client::sync::Stmt,
extractor: fn(&postgres::Row) -> crate::types::schema::NightmareCompositeBorrowed,
mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> T,
}
impl<'a, C, T: 'a, const N: usize> SchemaNightmareCompositeQuery<'a, C, T, N>
where
C: GenericClient,
{
pub fn map<R>(
self,
mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> R,
) -> SchemaNightmareCompositeQuery<'a, C, R, N> {
SchemaNightmareCompositeQuery {
client: self.client,
params: self.params,
stmt: self.stmt,
extractor: self.extractor,
mapper,
}
}
pub fn one(self) -> Result<T, postgres::Error> {
let stmt = self.stmt.prepare(self.client)?;
let row = self.client.query_one(stmt, &self.params)?;
Ok((self.mapper)((self.extractor)(&row)))
}
pub fn all(self) -> Result<Vec<T>, postgres::Error> {
self.iter()?.collect()
}
pub fn opt(self) -> Result<Option<T>, postgres::Error> {
let stmt = self.stmt.prepare(self.client)?;
Ok(self
.client
.query_opt(stmt, &self.params)?
.map(|row| (self.mapper)((self.extractor)(&row))))
}
pub fn iter(
self,
) -> Result<impl Iterator<Item = Result<T, postgres::Error>> + 'a, postgres::Error>
{
let stmt = self.stmt.prepare(self.client)?;
let it = self
.client
.query_raw(stmt, crate::slice_iter(&self.params))?
.iterator()
.map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))));
Ok(it)
}
}
pub fn select_everything() -> SelectEverythingStmt {
SelectEverythingStmt(crate::client::sync::Stmt::new(
"SELECT
Expand Down Expand Up @@ -1604,6 +1655,47 @@ FROM
client.execute(stmt, &[composite])
}
}
pub fn select_schema_nightmare() -> SelectSchemaNightmareStmt {
SelectSchemaNightmareStmt(crate::client::sync::Stmt::new(
"SELECT
*
FROM
schema.nightmare",
))
}
pub struct SelectSchemaNightmareStmt(crate::client::sync::Stmt);
impl SelectSchemaNightmareStmt {
pub fn bind<'a, C: GenericClient>(
&'a mut self,
client: &'a mut C,
) -> SchemaNightmareCompositeQuery<'a, C, crate::types::schema::NightmareComposite, 0>
{
SchemaNightmareCompositeQuery {
client,
params: [],
stmt: &mut self.0,
extractor: |row| row.get(0),
mapper: |it| it.into(),
}
}
}
pub fn insert_schema_nightmare() -> InsertSchemaNightmareStmt {
InsertSchemaNightmareStmt(crate::client::sync::Stmt::new(
"INSERT INTO schema.nightmare (composite)
VALUES ($1)",
))
}
pub struct InsertSchemaNightmareStmt(crate::client::sync::Stmt);
impl InsertSchemaNightmareStmt {
pub fn bind<'a, C: GenericClient>(
&'a mut self,
client: &'a mut C,
composite: &'a crate::types::schema::NightmareCompositeParams<'a>,
) -> Result<u64, postgres::Error> {
let stmt = self.0.prepare(client)?;
client.execute(stmt, &[composite])
}
}
}
pub mod async_ {
use crate::client::async_::GenericClient;
Expand Down Expand Up @@ -1883,6 +1975,61 @@ pub mod async_ {
Ok(it)
}
}
pub struct SchemaNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> {
client: &'a C,
params: [&'a (dyn postgres_types::ToSql + Sync); N],
stmt: &'a mut crate::client::async_::Stmt,
extractor: fn(&tokio_postgres::Row) -> crate::types::schema::NightmareCompositeBorrowed,
mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> T,
}
impl<'a, C, T: 'a, const N: usize> SchemaNightmareCompositeQuery<'a, C, T, N>
where
C: GenericClient,
{
pub fn map<R>(
self,
mapper: fn(crate::types::schema::NightmareCompositeBorrowed) -> R,
) -> SchemaNightmareCompositeQuery<'a, C, R, N> {
SchemaNightmareCompositeQuery {
client: self.client,
params: self.params,
stmt: self.stmt,
extractor: self.extractor,
mapper,
}
}
pub async fn one(self) -> Result<T, tokio_postgres::Error> {
let stmt = self.stmt.prepare(self.client).await?;
let row = self.client.query_one(stmt, &self.params).await?;
Ok((self.mapper)((self.extractor)(&row)))
}
pub async fn all(self) -> Result<Vec<T>, tokio_postgres::Error> {
self.iter().await?.try_collect().await
}
pub async fn opt(self) -> Result<Option<T>, tokio_postgres::Error> {
let stmt = self.stmt.prepare(self.client).await?;
Ok(self
.client
.query_opt(stmt, &self.params)
.await?
.map(|row| (self.mapper)((self.extractor)(&row))))
}
pub async fn iter(
self,
) -> Result<
impl futures::Stream<Item = Result<T, tokio_postgres::Error>> + 'a,
tokio_postgres::Error,
> {
let stmt = self.stmt.prepare(self.client).await?;
let it = self
.client
.query_raw(stmt, crate::slice_iter(&self.params))
.await?
.map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row))))
.into_stream();
Ok(it)
}
}
pub fn select_everything() -> SelectEverythingStmt {
SelectEverythingStmt(crate::client::async_::Stmt::new(
"SELECT
Expand Down Expand Up @@ -2569,4 +2716,45 @@ FROM
client.execute(stmt, &[composite]).await
}
}
pub fn select_schema_nightmare() -> SelectSchemaNightmareStmt {
SelectSchemaNightmareStmt(crate::client::async_::Stmt::new(
"SELECT
*
FROM
schema.nightmare",
))
}
pub struct SelectSchemaNightmareStmt(crate::client::async_::Stmt);
impl SelectSchemaNightmareStmt {
pub fn bind<'a, C: GenericClient>(
&'a mut self,
client: &'a C,
) -> SchemaNightmareCompositeQuery<'a, C, crate::types::schema::NightmareComposite, 0>
{
SchemaNightmareCompositeQuery {
client,
params: [],
stmt: &mut self.0,
extractor: |row| row.get(0),
mapper: |it| it.into(),
}
}
}
pub fn insert_schema_nightmare() -> InsertSchemaNightmareStmt {
InsertSchemaNightmareStmt(crate::client::async_::Stmt::new(
"INSERT INTO schema.nightmare (composite)
VALUES ($1)",
))
}
pub struct InsertSchemaNightmareStmt(crate::client::async_::Stmt);
impl InsertSchemaNightmareStmt {
pub async fn bind<'a, C: GenericClient>(
&'a mut self,
client: &'a C,
composite: &'a crate::types::schema::NightmareCompositeParams<'a>,
) -> Result<u64, tokio_postgres::Error> {
let stmt = self.0.prepare(client).await?;
client.execute(stmt, &[composite]).await
}
}
}
144 changes: 144 additions & 0 deletions test_codegen/codegen/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,3 +1199,147 @@ impl<'a> postgres_types::FromSql<'a> for SyntaxEnum {
}
}
}
pub mod schema {
#[derive(serde::Serialize, Debug, postgres_types :: FromSql, Clone, PartialEq)]
#[postgres(name = "nightmare_composite")]
pub struct NightmareComposite {
#[postgres(name = "custom")]
pub custom: Vec<super::CustomComposite>,
#[postgres(name = "spongebob")]
pub spongebob: Vec<super::SpongebobCharacter>,
#[postgres(name = "domain")]
pub domain: String,
}
#[derive(Debug)]
pub struct NightmareCompositeBorrowed<'a> {
pub custom: crate::ArrayIterator<'a, super::CustomCompositeBorrowed<'a>>,
pub spongebob: crate::ArrayIterator<'a, super::SpongebobCharacter>,
pub domain: &'a str,
}
impl<'a> From<NightmareCompositeBorrowed<'a>> for NightmareComposite {
fn from(
NightmareCompositeBorrowed {
custom,
spongebob,
domain,
}: NightmareCompositeBorrowed<'a>,
) -> Self {
Self {
custom: custom.map(|v| v.into()).collect(),
spongebob: spongebob.map(|v| v).collect(),
domain: domain.into(),
}
}
}
impl<'a> postgres_types::FromSql<'a> for NightmareCompositeBorrowed<'a> {
fn from_sql(
ty: &postgres_types::Type,
out: &'a [u8],
) -> Result<NightmareCompositeBorrowed<'a>, Box<dyn std::error::Error + Sync + Send>>
{
let fields = match *ty.kind() {
postgres_types::Kind::Composite(ref fields) => fields,
_ => unreachable!(),
};
let mut out = out;
let num_fields = postgres_types::private::read_be_i32(&mut out)?;
if num_fields as usize != fields.len() {
return std::result::Result::Err(std::convert::Into::into(format!(
"invalid field count: {} vs {}",
num_fields,
fields.len()
)));
}
let _oid = postgres_types::private::read_be_i32(&mut out)?;
let custom = postgres_types::private::read_value(fields[0].type_(), &mut out)?;
let _oid = postgres_types::private::read_be_i32(&mut out)?;
let spongebob = postgres_types::private::read_value(fields[1].type_(), &mut out)?;
let _oid = postgres_types::private::read_be_i32(&mut out)?;
let domain = postgres_types::private::read_value(fields[2].type_(), &mut out)?;
Ok(NightmareCompositeBorrowed {
custom,
spongebob,
domain,
})
}
fn accepts(ty: &postgres_types::Type) -> bool {
ty.name() == "nightmare_composite" && ty.schema() == "schema"
}
}
#[derive(Debug)]
pub struct NightmareCompositeParams<'a> {
pub custom: &'a [super::CustomCompositeBorrowed<'a>],
pub spongebob: &'a [super::SpongebobCharacter],
pub domain: &'a str,
}
impl<'a> postgres_types::ToSql for NightmareCompositeParams<'a> {
fn to_sql(
&self,
ty: &postgres_types::Type,
out: &mut postgres_types::private::BytesMut,
) -> Result<postgres_types::IsNull, Box<dyn std::error::Error + Sync + Send>> {
let NightmareCompositeParams {
custom,
spongebob,
domain,
} = self;
let fields = match *ty.kind() {
postgres_types::Kind::Composite(ref fields) => fields,
_ => unreachable!(),
};
out.extend_from_slice(&(fields.len() as i32).to_be_bytes());
for field in fields {
out.extend_from_slice(&field.type_().oid().to_be_bytes());
let base = out.len();
out.extend_from_slice(&[0; 4]);
let r = match field.name() {
"custom" => postgres_types::ToSql::to_sql(custom, field.type_(), out),
"spongebob" => postgres_types::ToSql::to_sql(spongebob, field.type_(), out),
"domain" => {
postgres_types::ToSql::to_sql(&crate::Domain(domain), field.type_(), out)
}
_ => unreachable!(),
};
let count = match r? {
postgres_types::IsNull::Yes => -1,
postgres_types::IsNull::No => {
let len = out.len() - base - 4;
if len > i32::max_value() as usize {
return Err(Into::into("value too large to transmit"));
}
len as i32
}
};
out[base..base + 4].copy_from_slice(&count.to_be_bytes());
}
Ok(postgres_types::IsNull::No)
}
fn accepts(ty: &postgres_types::Type) -> bool {
if ty.name() != "nightmare_composite" {
return false;
}
match *ty.kind() {
postgres_types::Kind::Composite(ref fields) => {
if fields.len() != 3 {
return false;
}
fields.iter().all(| f | match f.name()
{
"custom" => < &'a [super::CustomCompositeBorrowed<'a>] as postgres_types ::
ToSql > :: accepts(f.type_()),"spongebob" => < &'a [super::SpongebobCharacter] as postgres_types ::
ToSql > :: accepts(f.type_()),"domain" => < crate::Domain::<&'a str> as postgres_types ::
ToSql > :: accepts(f.type_()),_ => false,
})
}
_ => false,
}
}
fn to_sql_checked(
&self,
ty: &postgres_types::Type,
out: &mut postgres_types::private::BytesMut,
) -> Result<postgres_types::IsNull, Box<dyn std::error::Error + Sync + Send>> {
postgres_types::__to_sql_checked(self, ty, out)
}
}
}
11 changes: 11 additions & 0 deletions test_codegen/queries/stress.sql
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,14 @@ FROM
INSERT INTO nightmare (composite)
VALUES (:composite);


--! select_schema_nightmare
SELECT
*
FROM
schema.nightmare;

--! insert_schema_nightmare
INSERT INTO schema.nightmare (composite)
VALUES (:composite);

14 changes: 14 additions & 0 deletions test_codegen/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,20 @@ CREATE TABLE nightmare (
composite nightmare_composite NOT NULL
);

-- Schema

CREATE SCHEMA schema;

CREATE TYPE schema.nightmare_composite AS (
custom custom_composite[],
spongebob spongebob_character[],
domain my_domain
);

CREATE TABLE schema.nightmare (
composite schema.nightmare_composite NOT NULL
);

-- Syntax

CREATE TYPE syntax_composite AS (
Expand Down
Loading

0 comments on commit 8940433

Please sign in to comment.