Skip to content

Commit

Permalink
Merge pull request #4303 from PratikFandade/pg_row_to_json
Browse files Browse the repository at this point in the history
Add the row_to_json Method for diesel postgres
  • Loading branch information
weiznich authored Oct 25, 2024
2 parents a292e1d + 8ce5b1b commit 569c684
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
14 changes: 12 additions & 2 deletions diesel/src/pg/expression/expression_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ pub(in crate::pg) use self::private::{
ArrayOrNullableArray, CombinedNullableValue, InetOrCidr, JsonIndex, JsonOrNullableJson,
JsonOrNullableJsonOrJsonbOrNullableJsonb, JsonRemoveIndex, JsonbOrNullableJsonb,
MaybeNullableValue, MultirangeOrNullableMultirange, MultirangeOrRangeMaybeNullable,
RangeOrMultirange, RangeOrNullableRange, TextArrayOrNullableTextArray, TextOrNullableText,
RangeOrMultirange, RangeOrNullableRange, RecordOrNullableRecord, TextArrayOrNullableTextArray,
TextOrNullableText,
};
use super::date_and_time::{AtTimeZone, DateTimeLike};
use super::operators::*;
Expand Down Expand Up @@ -3302,7 +3303,7 @@ where
pub(in crate::pg) mod private {
use crate::sql_types::{
Array, Binary, Cidr, Inet, Integer, Json, Jsonb, MaybeNullableType, Multirange, Nullable,
OneIsNullable, Range, SingleValue, SqlType, Text,
OneIsNullable, Range, Record, SingleValue, SqlType, Text,
};
use crate::{Expression, IntoSql};

Expand Down Expand Up @@ -3640,4 +3641,13 @@ pub(in crate::pg) mod private {
impl TextArrayOrNullableTextArray for Array<Nullable<Text>> {}
impl TextArrayOrNullableTextArray for Nullable<Array<Text>> {}
impl TextArrayOrNullableTextArray for Nullable<Array<Nullable<Text>>> {}

#[diagnostic::on_unimplemented(
message = "`{Self}` is neither `Record<T>` nor `Nullable<Record<T>>`",
note = "try to provide an expression that produces one of the expected sql types"
)]
pub trait RecordOrNullableRecord {}

impl<T> RecordOrNullableRecord for Record<T> {}
impl<T> RecordOrNullableRecord for Nullable<Record<T>> {}
}
45 changes: 45 additions & 0 deletions diesel/src/pg/expression/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::pg::expression::expression_methods::MaybeNullableValue;
use crate::pg::expression::expression_methods::MultirangeOrNullableMultirange;
use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable;
use crate::pg::expression::expression_methods::RangeOrNullableRange;
use crate::pg::expression::expression_methods::RecordOrNullableRecord;
use crate::pg::expression::expression_methods::TextArrayOrNullableTextArray;
use crate::sql_types::*;

Expand Down Expand Up @@ -2234,3 +2235,47 @@ define_sql_function! {
values: Arr2
) -> Arr2::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
/// This function `row_to_json` takes a Record type as an input and converts it to JSON.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main() {
/// # #[cfg(feature = "serde_json")]
/// # run_test().unwrap();
/// # }
/// #
/// # #[cfg(feature = "serde_json")]
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::dsl::row_to_json;
/// # use diesel::dsl::sql;
/// # use diesel::sql_types::{Record, Text, Integer};
/// # use serde_json::Value;
/// # let connection = &mut establish_connection();
///
/// let json_value = diesel::select(row_to_json(sql::<Record<(Text, Integer)>>(
/// "ROW('John', 30)"
/// )))
/// .get_result::<Value>(connection)?;
/// let expected: Value = serde_json::json!({
/// "f1": "John",
/// "f2": 30
/// });
/// assert_eq!(expected, json_value);
///
/// let json_value = diesel::select(row_to_json(sql::<Record<()>>("ROW()")))
/// .get_result::<Value>(connection)?;
/// let expected: Value = serde_json::json!({});
/// assert_eq!(expected, json_value);
///
/// # Ok(())
/// # }
/// ```
#[sql_name = "row_to_json"]
fn row_to_json<R: RecordOrNullableRecord + MaybeNullableValue<Json>>(record: R) -> R::Out;
}
5 changes: 5 additions & 0 deletions diesel/src/pg/expression/helper_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,8 @@ pub type jsonb_object<A> = super::functions::jsonb_object<SqlTypeOf<A>, A>;
#[cfg(feature = "postgres_backend")]
pub type jsonb_object_with_keys_and_values<K, V> =
super::functions::jsonb_object_with_keys_and_values<SqlTypeOf<K>, SqlTypeOf<V>, K, V>;

/// Return type of [`row_to_json(record)`](super::functions::row_to_json())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type row_to_json<R> = super::functions::row_to_json<SqlTypeOf<R>, R>;
4 changes: 3 additions & 1 deletion diesel_derives/tests/auto_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ table! {
multirange -> Multirange<Integer>,
timestamptz -> Timestamptz,
name -> Text,
text_array -> Array<Text>
text_array -> Array<Text>,
record -> Record<(Integer, Text, Date)>,
}
}

Expand Down Expand Up @@ -449,6 +450,7 @@ fn postgres_functions() -> _ {
jsonb_array_length(pg_extras::jsonb),
jsonb_object(pg_extras::text_array),
jsonb_object_with_keys_and_values(pg_extras::text_array, pg_extras::text_array),
row_to_json(pg_extras::record),
)
}

Expand Down

0 comments on commit 569c684

Please sign in to comment.