ferd tomale
ferd tomale

Reputation: 903

How to use a user-defined type in a rust-postgres client.execute call

I have the following code that is used to insert email addresses in a table.

fn add(&mut self, email: &str) {
  match self.client.execute("call email_add($1)", &[&email]) {
    Ok(_) => {
      println!("inserted")
    }
    Err(e) => {
      println!("{:?}", e);
    }
  }
}

I get this error when I test the code:

Error { kind: ToSql(0), cause: Some(WrongType { postgres: Other(Other { name: "email_address", oid: 37434, kind: Domain(Text), schema: "public" }), rust: "&str" }) }

The email address user-defined type is defined as:

-- http://www.regular-expressions.info/email.html
create domain email_address
  text not null
  constraint chk_email
  check(
    length(value) < 254
    and
    value ~ '^[a-zA-Z0-9._%+-]{1,64}@(?:[a-zA-Z0-9-]{1,63}\.){1,125}[a-zA-Z]{2,63}$'
 );

I am using rust-postgres crate.

Upvotes: 3

Views: 446

Answers (1)

ferd tomale
ferd tomale

Reputation: 903

I had to implement the postgres_types::ToSql trait for the email_address domain that I created.

struct EmailAddress {
  email: String
}

impl ToSql for EmailAddress {
  fn to_sql(&self, ty: &Type, out: &mu BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
    return self.email.to_sql(ty, out);
  }
  
  to_sql_checked!();

  fn accepts(ty: &Type) -> bool {
    return ty.name() == "email_address";
  }
}

Then I changed the add function to:

fn add(&mut self, email: &str) {
  let email_address: EmailAddress = EmailAddress {
    email: String::from(email)
  }
  match self.client.execute("call email_add($1)", &[&email_address]) {
    Ok(_) => {
      println!("inserted")
    }
    Err(e) => {
      println!("{:?}", e);
    }
  }
}

Upvotes: 2

Related Questions