Add Support For PostgreSQL Arrays In FromQueryResult Implementation Of 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 <ccw.billy.123@gmail.com>
This commit is contained in:
parent
63d8cdf7e5
commit
5fa2c1c28c
@ -77,6 +77,7 @@ impl FromQueryResult for JsonValue {
|
|||||||
crate::QueryResultRow::SqlxPostgres(row) => {
|
crate::QueryResultRow::SqlxPostgres(row) => {
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use sqlx::{postgres::types::Oid, Column, Postgres, Row, Type};
|
use sqlx::{postgres::types::Oid, Column, Postgres, Row, Type};
|
||||||
|
|
||||||
for column in row.columns() {
|
for column in row.columns() {
|
||||||
let col = if !column.name().starts_with(pre) {
|
let col = if !column.name().starts_with(pre) {
|
||||||
continue;
|
continue;
|
||||||
@ -84,13 +85,25 @@ impl FromQueryResult for JsonValue {
|
|||||||
column.name().replacen(pre, "", 1)
|
column.name().replacen(pre, "", 1)
|
||||||
};
|
};
|
||||||
let col_type = column.type_info();
|
let col_type = column.type_info();
|
||||||
|
|
||||||
macro_rules! match_postgres_type {
|
macro_rules! match_postgres_type {
|
||||||
( $type: ty ) => {
|
( $type: ty ) => {
|
||||||
if <$type as Type<Postgres>>::type_info().eq(col_type) {
|
match col_type.kind() {
|
||||||
try_get_type!($type, col)
|
#[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!(bool);
|
||||||
match_postgres_type!(i8);
|
match_postgres_type!(i8);
|
||||||
match_postgres_type!(i16);
|
match_postgres_type!(i16);
|
||||||
@ -126,9 +139,15 @@ impl FromQueryResult for JsonValue {
|
|||||||
match_postgres_type!(rust_decimal::Decimal);
|
match_postgres_type!(rust_decimal::Decimal);
|
||||||
#[cfg(feature = "with-json")]
|
#[cfg(feature = "with-json")]
|
||||||
try_get_type!(serde_json::Value, col);
|
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);
|
try_get_type!(String, col);
|
||||||
|
#[cfg(feature = "postgres-array")]
|
||||||
|
try_get_type!(Vec<String>, col);
|
||||||
#[cfg(feature = "with-uuid")]
|
#[cfg(feature = "with-uuid")]
|
||||||
try_get_type!(uuid::Uuid, col);
|
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);
|
try_get_type!(Vec<u8>, col);
|
||||||
}
|
}
|
||||||
Ok(JsonValue::Object(map))
|
Ok(JsonValue::Object(map))
|
||||||
|
@ -5,6 +5,7 @@ use pretty_assertions::assert_eq;
|
|||||||
use sea_orm::{
|
use sea_orm::{
|
||||||
entity::prelude::*, entity::*, DatabaseConnection, DerivePartialModel, FromQueryResult,
|
entity::prelude::*, entity::*, DatabaseConnection, DerivePartialModel, FromQueryResult,
|
||||||
};
|
};
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
#[sea_orm_macros::test]
|
#[sea_orm_macros::test]
|
||||||
#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))]
|
#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))]
|
||||||
@ -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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user