Skip to content

Commit

Permalink
added jsonb_insert
Browse files Browse the repository at this point in the history
  • Loading branch information
Azan Ali authored and Azan Ali committed Sep 18, 2024
1 parent 810c3e3 commit c2d9b2c
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
97 changes: 97 additions & 0 deletions diesel/src/pg/expression/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2078,3 +2078,100 @@ define_sql_function! {

fn jsonb_array_length<E: JsonbOrNullableJsonb + MaybeNullableValue<Integer>>(jsonb: E) -> E::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
/// Returns target with new_value inserted, if the item designated by the path is an array element.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::dsl::jsonb_insert;
/// # use diesel::sql_types::{Array, Jsonb, Nullable, Text};
/// # use serde_json::{Value, json};
/// # let connection = &mut establish_connection();
/// let result = diesel::select(jsonb_insert::<Jsonb, Array<Text>, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1)))
/// .get_result::<Value>(connection)?;
/// assert_eq!(json!([1, 2, 1, 3]), result);
///
/// let result = diesel::select(jsonb_insert::<Jsonb, Array<Text>, _, _, _>(json!([1, 2, 3]), Vec::<String>::new(), json!(1)))
/// .get_result::<Value>(connection)?;
/// assert_eq!(json!([1, 2, 3]), result);
///
/// let result = diesel::select(jsonb_insert::<Nullable<Jsonb>, Array<Text>, _, _, _>(Option::<Value>::None, vec!["1"], json!(1)))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
/// let result = diesel::select(jsonb_insert::<Jsonb, Nullable<Array<Text>>, _, _, _>(json!([1, 2, 3]), None::<Vec<String>>, json!(1)))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
/// let result = diesel::select(jsonb_insert::<Nullable<Jsonb>, Array<Text>, _, _, _>(json!([1, 2, 3]), vec!["1"], Option::<Value>::None))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
///
/// # Ok(())
/// # }
/// ```
fn jsonb_insert<J: JsonbOrNullableJsonb + SingleValue, P: TextArrayOrNullableTextArray + CombinedNullableValue<J, Jsonb>>(target: J, path: P, value: J) -> P::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
/// Returns target with new_value inserted, if the item designated by the path is an array element.
/// If insert_after is true, the value is inserted after the path specified
///
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// #
/// # fn main() {
/// # run_test().unwrap();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// # use diesel::dsl::jsonb_insert_with_option_after;
/// # use diesel::sql_types::{Array, Jsonb, Nullable, Text};
/// # use serde_json::{Value, json};
/// # let connection = &mut establish_connection();
/// let result = diesel::select(jsonb_insert_with_option_after::<Jsonb, Array<Text>, _, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1), true))
/// .get_result::<Value>(connection)?;
/// assert_eq!(json!([1, 2, 3, 1]), result);
///
/// let result = diesel::select(jsonb_insert_with_option_after::<Jsonb, Array<Text>, _, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1), false))
/// .get_result::<Value>(connection)?;
/// assert_eq!(json!([1, 2, 1, 3]), result);
///
/// let result = diesel::select(jsonb_insert_with_option_after::<Jsonb, Array<Text>, _, _, _, _>(json!([1, 2, 3]), Vec::<String>::new(), json!(1), true))
/// .get_result::<Value>(connection)?;
/// assert_eq!(json!([1, 2, 3]), result);
///
/// let result = diesel::select(jsonb_insert_with_option_after::<Nullable<Jsonb>, Array<Text>, _, _, _, _>(Option::<Value>::None, vec!["1"], json!(1), true))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
/// let result = diesel::select(jsonb_insert_with_option_after::<Jsonb, Nullable<Array<Text>>, _, _, _, _>(json!([1, 2, 3]), None::<Vec<String>>, json!(1), true))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
/// let result = diesel::select(jsonb_insert_with_option_after::<Nullable<Jsonb>, Array<Text>, _, _, _, _>(json!([1, 2, 3]), vec!["1"], Option::<Value>::None, true))
/// .get_result::<Option<Value>>(connection)?;
/// assert_eq!(None, result);
///
///
/// # Ok(())
/// # }
/// ```
#[sql_name = "jsonb_insert"]
fn jsonb_insert_with_option_after<J: JsonbOrNullableJsonb + SingleValue, P: TextArrayOrNullableTextArray + CombinedNullableValue<J, Jsonb>>(target: J, path: P, value: J, insert_after: Bool) -> P::Out;
}
12 changes: 12 additions & 0 deletions diesel/src/pg/expression/helper_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,15 @@ pub type json_array_length<E> = super::functions::json_array_length<SqlTypeOf<E>
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type jsonb_array_length<E> = super::functions::jsonb_array_length<SqlTypeOf<E>, E>;

/// Return type of [`jsonb_insert(target, path, value)`](super::functions::jsonb_insert())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type jsonb_insert<T, P, V> =
super::functions::jsonb_insert<SqlTypeOf<T>, SqlTypeOf<P>, T, P, V>;

/// Return type of [`jsonb_insert(target, path, value, insert_after)`](super::functions::jsonb_insert_with_option_after())
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type jsonb_insert_with_option_after<T, P, V, I> =
super::functions::jsonb_insert_with_option_after<SqlTypeOf<T>, SqlTypeOf<P>, T, P, V, I>;
8 changes: 8 additions & 0 deletions diesel_derives/tests/auto_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ table! {
table! {
pg_extras(id) {
id -> Integer,
boolean -> Bool,
json -> Json,
jsonb -> Jsonb,
net -> Inet,
Expand Down Expand Up @@ -446,6 +447,13 @@ fn postgres_functions() -> _ {
jsonb_strip_nulls(pg_extras::jsonb),
json_array_length(pg_extras::json),
jsonb_array_length(pg_extras::jsonb),
jsonb_insert(pg_extras::jsonb, pg_extras::text_array, pg_extras::jsonb),
jsonb_insert_with_option_after(
pg_extras::jsonb,
pg_extras::text_array,
pg_extras::jsonb,
pg_extras::boolean,
),
)
}

Expand Down

0 comments on commit c2d9b2c

Please sign in to comment.