From c2d9b2c0a817fe99e62b551e7620d00aeb1f59ff Mon Sep 17 00:00:00 2001 From: Azan Ali Date: Thu, 12 Sep 2024 15:34:07 +0500 Subject: [PATCH] added jsonb_insert --- diesel/src/pg/expression/functions.rs | 97 ++++++++++++++++++++++++ diesel/src/pg/expression/helper_types.rs | 12 +++ diesel_derives/tests/auto_type.rs | 8 ++ 3 files changed, 117 insertions(+) diff --git a/diesel/src/pg/expression/functions.rs b/diesel/src/pg/expression/functions.rs index cc793ae3092b..6dc0a808a3eb 100644 --- a/diesel/src/pg/expression/functions.rs +++ b/diesel/src/pg/expression/functions.rs @@ -2078,3 +2078,100 @@ define_sql_function! { fn jsonb_array_length>(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::, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1))) + /// .get_result::(connection)?; + /// assert_eq!(json!([1, 2, 1, 3]), result); + /// + /// let result = diesel::select(jsonb_insert::, _, _, _>(json!([1, 2, 3]), Vec::::new(), json!(1))) + /// .get_result::(connection)?; + /// assert_eq!(json!([1, 2, 3]), result); + /// + /// let result = diesel::select(jsonb_insert::, Array, _, _, _>(Option::::None, vec!["1"], json!(1))) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// let result = diesel::select(jsonb_insert::>, _, _, _>(json!([1, 2, 3]), None::>, json!(1))) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// let result = diesel::select(jsonb_insert::, Array, _, _, _>(json!([1, 2, 3]), vec!["1"], Option::::None)) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// + /// # Ok(()) + /// # } + /// ``` + fn jsonb_insert>(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::, _, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1), true)) + /// .get_result::(connection)?; + /// assert_eq!(json!([1, 2, 3, 1]), result); + /// + /// let result = diesel::select(jsonb_insert_with_option_after::, _, _, _, _>(json!([1, 2, 3]), vec!["2"], json!(1), false)) + /// .get_result::(connection)?; + /// assert_eq!(json!([1, 2, 1, 3]), result); + /// + /// let result = diesel::select(jsonb_insert_with_option_after::, _, _, _, _>(json!([1, 2, 3]), Vec::::new(), json!(1), true)) + /// .get_result::(connection)?; + /// assert_eq!(json!([1, 2, 3]), result); + /// + /// let result = diesel::select(jsonb_insert_with_option_after::, Array, _, _, _, _>(Option::::None, vec!["1"], json!(1), true)) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// let result = diesel::select(jsonb_insert_with_option_after::>, _, _, _, _>(json!([1, 2, 3]), None::>, json!(1), true)) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// let result = diesel::select(jsonb_insert_with_option_after::, Array, _, _, _, _>(json!([1, 2, 3]), vec!["1"], Option::::None, true)) + /// .get_result::>(connection)?; + /// assert_eq!(None, result); + /// + /// + /// # Ok(()) + /// # } + /// ``` + #[sql_name = "jsonb_insert"] + fn jsonb_insert_with_option_after>(target: J, path: P, value: J, insert_after: Bool) -> P::Out; +} diff --git a/diesel/src/pg/expression/helper_types.rs b/diesel/src/pg/expression/helper_types.rs index c5394a1ecd5d..76c190d00add 100644 --- a/diesel/src/pg/expression/helper_types.rs +++ b/diesel/src/pg/expression/helper_types.rs @@ -527,3 +527,15 @@ pub type json_array_length = super::functions::json_array_length #[allow(non_camel_case_types)] #[cfg(feature = "postgres_backend")] pub type jsonb_array_length = super::functions::jsonb_array_length, 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 = + super::functions::jsonb_insert, SqlTypeOf

, 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 = + super::functions::jsonb_insert_with_option_after, SqlTypeOf

, T, P, V, I>; diff --git a/diesel_derives/tests/auto_type.rs b/diesel_derives/tests/auto_type.rs index deaedaec3dc4..f54dfb7dd032 100644 --- a/diesel_derives/tests/auto_type.rs +++ b/diesel_derives/tests/auto_type.rs @@ -42,6 +42,7 @@ table! { table! { pg_extras(id) { id -> Integer, + boolean -> Bool, json -> Json, jsonb -> Jsonb, net -> Inet, @@ -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, + ), ) }