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

Support Postgres network types (inet) #888 #1470

Closed
wants to merge 3 commits into from
Closed

Support Postgres network types (inet) #888 #1470

wants to merge 3 commits into from

Conversation

tusharxoxoxo
Copy link
Contributor

@tusharxoxoxo tusharxoxoxo commented Feb 10, 2023

PR Info

#888
created a separate function for adding support for inet. I am not sure whether I have done it right or not. someone please point out mistakes and guide me to fix this.

  • Closes
  • Dependencies:
  • Dependents:

New Features

added inet support using ipnet

Bug Fixes

Breaking Changes

Changes

Copy link
Member

@billy1624 billy1624 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @tusharxoxoxo, thanks for contributing!!

I think we should support the follow three network types in SeaORM.

  1. ipnetwork::IpNetwork
  2. std::net::IpAddr
  3. mac_address::MacAddress

We need to change the following places to support decoding those network types from (mock) query result.

  1. Get the address types from QueryResultRow::SqlxPostgres to construct the model while leaving other QueryResultRow returns Err

    macro_rules! try_getable_mysql {
    ( $type: ty ) => {
    impl TryGetable for $type {
    #[allow(unused_variables)]
    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {
    match &res.row {
    #[cfg(feature = "sqlx-mysql")]
    QueryResultRow::SqlxMySql(row) => row
    .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())
    .map_err(|e| sqlx_error_to_query_err(e).into())
    .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),
    #[cfg(feature = "sqlx-postgres")]
    QueryResultRow::SqlxPostgres(_) => Err(type_err(format!(
    "{} unsupported by sqlx-postgres",
    stringify!($type)
    ))
    .into()),
    #[cfg(feature = "sqlx-sqlite")]
    QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(
    "{} unsupported by sqlx-sqlite",
    stringify!($type)
    ))
    .into()),
    #[cfg(feature = "mock")]
    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {
    debug_print!("{:#?}", e.to_string());
    err_null_idx_col(idx)
    }),
    #[allow(unreachable_patterns)]
    _ => unreachable!(),
    }
    }
    }
    };
    }
    #[allow(unused_macros)]
    macro_rules! try_getable_date_time {
    ( $type: ty ) => {
    impl TryGetable for $type {
    #[allow(unused_variables)]
    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {
    match &res.row {
    #[cfg(feature = "sqlx-mysql")]
    QueryResultRow::SqlxMySql(row) => {
    use chrono::{DateTime, Utc};
    row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_mysql_index())
    .map_err(|e| sqlx_error_to_query_err(e).into())
    .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))
    .map(|v| v.into())
    }
    #[cfg(feature = "sqlx-postgres")]
    QueryResultRow::SqlxPostgres(row) => row
    .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())
    .map_err(|e| sqlx_error_to_query_err(e).into())
    .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),
    #[cfg(feature = "sqlx-sqlite")]
    QueryResultRow::SqlxSqlite(row) => {
    use chrono::{DateTime, Utc};
    row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_sqlite_index())
    .map_err(|e| sqlx_error_to_query_err(e).into())
    .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))
    .map(|v| v.into())
    }
    #[cfg(feature = "mock")]
    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {
    debug_print!("{:#?}", e.to_string());
    err_null_idx_col(idx)
    }),
    #[allow(unreachable_patterns)]
    _ => unreachable!(),
    }
    }
    }
    };
    }
    try_getable_all!(bool);
    try_getable_all!(i8);
    try_getable_all!(i16);
    try_getable_all!(i32);
    try_getable_all!(i64);
    try_getable_unsigned!(u8);
    try_getable_unsigned!(u16);
    try_getable_mysql!(u64);
    try_getable_all!(f32);
    try_getable_all!(f64);
    try_getable_all!(String);
    try_getable_all!(Vec<u8>);

  2. Get the address types from QueryResultRow::SqlxPostgres to construct the JSON object

    sea-orm/src/query/json.rs

    Lines 76 to 135 in 92aa919

    #[cfg(feature = "sqlx-postgres")]
    crate::QueryResultRow::SqlxPostgres(row) => {
    use serde_json::json;
    use sqlx::{postgres::types::Oid, Column, Postgres, Row, Type};
    for column in row.columns() {
    let col = if !column.name().starts_with(pre) {
    continue;
    } else {
    column.name().replacen(pre, "", 1)
    };
    let col_type = column.type_info();
    macro_rules! match_postgres_type {
    ( $type: ty ) => {
    if <$type as Type<Postgres>>::type_info().eq(col_type) {
    try_get_type!($type, col)
    }
    };
    }
    match_postgres_type!(bool);
    match_postgres_type!(i8);
    match_postgres_type!(i16);
    match_postgres_type!(i32);
    match_postgres_type!(i64);
    // match_postgres_type!(u8); // unsupported by SQLx Postgres
    // match_postgres_type!(u16); // unsupported by SQLx Postgres
    // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;
    // Instead, `u32` was wrapped by a `sqlx::Oid`.
    if <Oid as Type<Postgres>>::type_info().eq(col_type) {
    try_get_type!(u32, col)
    }
    // match_postgres_type!(u64); // unsupported by SQLx Postgres
    match_postgres_type!(f32);
    match_postgres_type!(f64);
    #[cfg(feature = "with-chrono")]
    match_postgres_type!(chrono::NaiveDate);
    #[cfg(feature = "with-chrono")]
    match_postgres_type!(chrono::NaiveTime);
    #[cfg(feature = "with-chrono")]
    match_postgres_type!(chrono::NaiveDateTime);
    #[cfg(feature = "with-chrono")]
    match_postgres_type!(chrono::DateTime<chrono::FixedOffset>);
    #[cfg(feature = "with-time")]
    match_postgres_type!(time::Date);
    #[cfg(feature = "with-time")]
    match_postgres_type!(time::Time);
    #[cfg(feature = "with-time")]
    match_postgres_type!(time::PrimitiveDateTime);
    #[cfg(feature = "with-time")]
    match_postgres_type!(time::OffsetDateTime);
    #[cfg(feature = "with-rust_decimal")]
    match_postgres_type!(rust_decimal::Decimal);
    #[cfg(feature = "with-json")]
    try_get_type!(serde_json::Value, col);
    try_get_type!(String, col);
    #[cfg(feature = "with-uuid")]
    try_get_type!(uuid::Uuid, col);
    try_get_type!(Vec<u8>, col);
    }
    Ok(JsonValue::Object(map))
    }

@tusharxoxoxo
Copy link
Contributor Author

I am on it. If I have any doubts/confusion then I will ask on discord. thanks billy

@yallxe
Copy link

yallxe commented Aug 28, 2023

Any updates on this? Maybe need some help?

@tusharxoxoxo
Copy link
Contributor Author

tusharxoxoxo commented Aug 28, 2023 via email

@yallxe
Copy link

yallxe commented Aug 28, 2023

No needs to be sorry, it's okay ;) I'm here to help if needed, I kind of need that feature too.

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

Successfully merging this pull request may close these issues.

3 participants