Skip to content

Commit

Permalink
Add Support For PostgreSQL Arrays In FromQueryResult Implementation O…
Browse files Browse the repository at this point in the history
…f JsonValue (#1598)

* Add Support For PostgreSQL Arrays In FromQueryResult Implementation Of JsonValue

* Add support for root arrays in JSON in SeaORM #1517

* Refactoring

* Only when `postgres-array` is enabled

* Add test cases

---------

Co-authored-by: Billy Chan <[email protected]>
  • Loading branch information
anshap1719 and billy1624 authored Aug 1, 2023
1 parent 63d8cdf commit 5fa2c1c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/query/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,33 @@ impl FromQueryResult for JsonValue {
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 col_type.kind() {
#[cfg(feature = "postgres-array")]
sqlx::postgres::PgTypeKind::Array(_) => {
if <Vec<$type> as Type<Postgres>>::type_info().eq(col_type) {
try_get_type!(Vec<$type>, col);
}
}
_ => {
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);
Expand Down Expand Up @@ -126,9 +139,15 @@ impl FromQueryResult for JsonValue {
match_postgres_type!(rust_decimal::Decimal);
#[cfg(feature = "with-json")]
try_get_type!(serde_json::Value, col);
#[cfg(all(feature = "with-json", feature = "postgres-array"))]
try_get_type!(Vec<serde_json::Value>, col);
try_get_type!(String, col);
#[cfg(feature = "postgres-array")]
try_get_type!(Vec<String>, col);
#[cfg(feature = "with-uuid")]
try_get_type!(uuid::Uuid, col);
#[cfg(all(feature = "with-uuid", feature = "postgres-array"))]
try_get_type!(Vec<uuid::Uuid>, col);
try_get_type!(Vec<u8>, col);
}
Ok(JsonValue::Object(map))
Expand Down
49 changes: 49 additions & 0 deletions tests/collection_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use pretty_assertions::assert_eq;
use sea_orm::{
entity::prelude::*, entity::*, DatabaseConnection, DerivePartialModel, FromQueryResult,
};
use serde_json::json;

#[sea_orm_macros::test]
#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))]
Expand Down Expand Up @@ -114,6 +115,54 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {
}
);

assert_eq!(
Entity::find_by_id(1).into_json().one(db).await?,
Some(json!({
"id": 1,
"name": "Collection 1",
"integers": [1, 2, 3],
"integers_opt": [1, 2, 3],
"teas": ["BreakfastTea"],
"teas_opt": ["BreakfastTea"],
"colors": [0],
"colors_opt": [0],
"uuid": [uuid],
"uuid_hyphenated": [uuid.hyphenated()],
}))
);

assert_eq!(
Entity::find_by_id(2).into_json().one(db).await?,
Some(json!({
"id": 2,
"name": "Collection 2",
"integers": [10, 9],
"integers_opt": null,
"teas": ["BreakfastTea"],
"teas_opt": null,
"colors": [0],
"colors_opt": null,
"uuid": [uuid],
"uuid_hyphenated": [uuid.hyphenated()],
}))
);

assert_eq!(
Entity::find_by_id(3).into_json().one(db).await?,
Some(json!({
"id": 3,
"name": "Collection 3",
"integers": [],
"integers_opt": [],
"teas": [],
"teas_opt": [],
"colors": [],
"colors_opt": [],
"uuid": [uuid],
"uuid_hyphenated": [uuid.hyphenated()],
}))
);

Ok(())
}

Expand Down

0 comments on commit 5fa2c1c

Please sign in to comment.