Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sqlx::any::AnyTypeInfoKind is private, cannot implement Type<Any> #3599

Open
rnza0u opened this issue Nov 10, 2024 · 2 comments
Open

sqlx::any::AnyTypeInfoKind is private, cannot implement Type<Any> #3599

rnza0u opened this issue Nov 10, 2024 · 2 comments
Labels

Comments

@rnza0u
Copy link

rnza0u commented Nov 10, 2024

Bug Description

Hello !

When using the Any driver, we run into some issues when creating custom decoders.

#[derive(sqlx::Type)] only generate Decode implementations for specific drivers (Type<Postgres>, Type<Sqlite>, Decode<Postgres>, Decode<Sqlite> etc...). It does not generate implementations for the Any driver.

Implementing a custom Decode can be done for the Any driver. However, it seems like it is impossible to write a Type implementation since there are no ways to return a AnyTypeInfo from outside the sqlx crate.

The reason is that sqlx::any::AnyTypeInfoKind is not exported within the library.

Is there a workaround that ?

Thank you...

Info

  • SQLx version: 0.8.2
  • SQLx features enabled: ["tls-rustls", "runtime-tokio", "postgres", "sqlite", "uuid", "chrono"]
  • Database server and version: Sqlite and postgres
  • Operating system: Linux
  • rustc --version: 1.81.0
@rnza0u rnza0u added the bug label Nov 10, 2024
@abonander
Copy link
Collaborator

You can forward to an existing impl. That is the intent, and is what the derives do.

@rnza0u
Copy link
Author

rnza0u commented Nov 11, 2024

Thank a lot. I just tried it, and it works indeed !

Here is an implementation of a Decoder for chrono::DateTime that would work with the Any driver.

At runtime, it works for SQLite, i haven't tried with other DBMS so be careful !

The encoding of the date objects when inserting/updating rows is done with chrono::DateTime::to_rfc3339.

pub struct StoredDateTime(DateTime<Utc>);

impl StoredDateTime {
    pub fn unwrap(self) -> DateTime<Utc> {
        self.0
    }
}

impl<'r, DB: sqlx::Database> Decode<'r, DB> for StoredDateTime
where
    &'r str: Decode<'r, DB>,
{
    fn decode(
        value: <DB as sqlx::Database>::ValueRef<'r>,
    ) -> std::result::Result<Self, BoxDynError> {
        let value = <&str as Decode<DB>>::decode(value)?;
        Ok(StoredDateTime(
            DateTime::parse_from_rfc3339(value)?.to_utc(),
        ))
    }
}

impl<'r, DB: sqlx::Database> sqlx::Type<DB> for StoredDateTime
where
    &'r str: sqlx::Type<DB>,
{
    fn type_info() -> DB::TypeInfo {
        <&str as sqlx::Type<DB>>::type_info()
    }
}

Do you think that would be a valid approach ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants