Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Matthew Pocock
    @drdozer
    this is fine:
    #[derive(DieselNewType)]
    #[derive(Debug, Hash, PartialEq, Eq)]
    pub struct HashedPassword(String);
    but
    #[derive(Insertable)]
    #[table_name="authenticated_user"]
    pub struct NewUser<'a> {
      pub email_address: &'a str,
      pub hashed_password: &'a HashedPassword,
    }
    this fails with
    15 | #[derive(Insertable)]
       |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `models::HashedPassword`
    Georg Semmler
    @weiznich
    Is that the whole error message?
    Matthew Pocock
    @drdozer
    so it seems that the Insertable derive macro is binding directly to Expression, rather than via AsExpression :(
    Georg Semmler
    @weiznich
    No, that's wrong. Insertable certainly supports that.
    Matthew Pocock
    @drdozer
    OK .. is there a way to view just the failing macro expansion? To view the macro-expanded source for the failing derive?
    Georg Semmler
    @weiznich
    Again, is that the full error message with all notes and other stuff?
    Matthew Pocock
    @drdozer
    error[E0277]: the trait bound `models::HashedPassword: diesel::Expression` is not satisfied
      --> db_model/src/models.rs:15:10
       |
    15 | #[derive(Insertable)]
       |          ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `models::HashedPassword`
       |
       = note: required because of the requirements on the impl of `diesel::Expression` for `&models::HashedPassword`
    Georg Semmler
    @weiznich
    From looking at their code it seems like they miss various AsExpression impls for combinations of Nullable<> and references. That could cause that.
    I would probably just use plain diesel to implement that what you want.
    Matthew Pocock
    @drdozer
    OK, looks like that's most likely the shortest path to working ;)
    So what is the minimum I need to implement?
    Georg Semmler
    @weiznich
    It's basically this test case but you would use an existing sql type instead of the newly created one in that example.
    Matthew Pocock
    @drdozer
    So impl ToSql<?text?, Pg> for HashedPassword { ... } and the corresponding FromSql?
    where <?text?> is whatever type is used for varchar?
    Georg Semmler
    @weiznich
    • The derives on tHashedPassword.
    <?text?> is the type in your table definition :wink:
    Matthew Pocock
    @drdozer
    Varchar
    Georg Semmler
    @weiznich
    Then you use diesel::sql_types::Varchar there.
    Matthew Pocock
    @drdozer
    great, so this seems to compile:
    #[derive(Debug, PartialEq, FromSqlRow, AsExpression)]
    #[sql_type="Varchar"]
    pub struct HashedPassword(String);
    with the appropriate import
    Georg Semmler
    @weiznich
    :+1:
    Matthew Pocock
    @drdozer
    ah - do I need to manually provide implementations of from/to sql that do the (un)boxing through the newtype?
    Georg Semmler
    @weiznich
    Yes, that's required.
    (If you only use the type in insert statements, then only ToSql may be required…)
    Matthew Pocock
    @drdozer
    thanks ... ok so I'm trying to find the rust incantation to summon the FromSql instance for String from Varchar so that I can just transform that result
    this is clearly the wrong rust-salad: (String as FromSql<Varchar, Pg>)::from_sql(bytes)
    ah so this appears to compile: FromSql::<Varchar, Pg>::from_sql(bytes)
    Matthew Pocock
    @drdozer
    For the sake of future people asking google, here's the working code fragments:
    #[derive(Debug, PartialEq, FromSqlRow, AsExpression)]
    #[sql_type="Varchar"]
    pub struct HashedPassword(String);
    
    impl FromSql<Varchar, Pg> for HashedPassword {
      fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
        FromSql::<Varchar, Pg>::from_sql(bytes).map(HashedPassword)
      }
    }
    
    impl ToSql<Varchar, Pg> for HashedPassword {
      fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
        ToSql::<Varchar, Pg>::to_sql(&self.0, out)
      }
    }
    Etienne
    @Farkal
    Hey ! Is there a way to have the pagination implementation boxed ? -> https://github.com/diesel-rs/diesel/blob/master/examples/postgres/advanced-blog-cli/src/pagination.rs
    Georg Semmler
    @weiznich
    What part do you want to box exactly?
    Etienne
    @Farkal
    The call to paginate and per_page on a boxed query, like you can conditionaly build a request
    Georg Semmler
    @weiznich
    Have you tried that? It should just work as far as I can see
    Etienne
    @Farkal
    let mut request = layers_table.into_boxed();
        if let Some(criterias) = criterias {
            if let Some(identifier) = criterias.identifier {
                request = request.filter(col_identifier.ilike(format!("%{}%", identifier)));
            }
            if let Some(layer_ids) = criterias.layer_ids {
                request = request.filter(col_id.eq_any(layer_ids));
            }
            if let Some(pagination) = criterias.pagination {
                request = request.paginate(pagination.page.into());
                if let Some(per_page) = pagination.per_page {
                    request = query.per_page(per_page.into());
                } 
            }
        }
        Ok(request.load(&pool.get()?)?)
    This code doesn't work
    i get: expected struct diesel::query_builder::BoxedSelectStatement, found struct pagination::Paginated
    Georg Semmler
    @weiznich
    That's expected. I do not see any way to make that working without reimplementing a more general variant of BoxedSelectStatement outside of diesel.
    Etienne
    @Farkal
    Ok so i will need to split my request in case it have been paginated and the case it haven't
    Georg Semmler
    @weiznich
    The problem there is: Not each select statement is a paginated query. We cannot let you perform actions like .per_page on a ordinary select statement, because they do not make any sense there.
    Etienne
    @Farkal
    Yeah it's true
    Georg Semmler
    @weiznich
    Additionally the returned types change.
    Etienne
    @Farkal
    Can't we box the return to make it generic ? :D
    Georg Semmler
    @weiznich
    No, at least diesel need to know what types are returned at compile time to load the types. How would the type returned by load look for this case?
    Etienne
    @Farkal
    Yeah we would loose all the interest of diesel, i came from js and dynamic type still disturb me
    matrixbot
    @matrixbot

    gondolyr I'm trying to convert my custom enum to a SmallInt (i16) for a struct that derives Insertable. I'm using Sqlite as my DB engine and have tried to follow some threads like diesel-rs/diesel#503 to try to help.

    I get the following error:

     | #[derive(Identifiable, Insertable, Queryable, Serialize, Deserialize)]
       |                        ^^^^^^^^^^ the trait `diesel::Expression` is not implemented for `models::show::PublicationStatus`

    Here is a link to my code where I'm trying to serialize the PublicationStatus enum: https://gist.github.com/7fa89c49724e36465ec9017de8bddce5

    Georg Semmler
    @weiznich
    Basically this: :point_up: January 28, 2020 2:16 PM
    (You need to adjust the FromSql/ToSql impl and the sql type)
    matrixbot
    @matrixbot
    gondolyr Oh, I didn't realize someone else posted a similar issue
    matrixbot
    @matrixbot
    gondolyr Thanks Georg Semmler (Gitter), I got it to work following that! :)