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 ecf6e92 commit 2a9e3df
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
101 changes: 99 additions & 2 deletions diesel/src/pg/expression/functions.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! PostgreSQL specific functions

use super::expression_methods::InetOrCidr;
use super::expression_methods::JsonbOrNullableJsonb;
use crate::expression::functions::define_sql_function;
use crate::pg::expression::expression_methods::ArrayOrNullableArray;
use crate::pg::expression::expression_methods::CombinedNullableValue;
use crate::pg::expression::expression_methods::JsonOrNullableJson;
use crate::pg::expression::expression_methods::JsonbOrNullableJsonb;
use crate::pg::expression::expression_methods::MaybeNullableValue;
use crate::pg::expression::expression_methods::MultirangeOrNullableMultirange;
use crate::pg::expression::expression_methods::MultirangeOrRangeMaybeNullable;
Expand Down Expand Up @@ -1692,7 +1692,7 @@ define_sql_function! {
/// let json = diesel::select(json_object_with_keys_and_values::<Array<Text>, Array<Text>, _, _>(
/// vec!["hello","John"], empty))
/// .get_result::<Value>(connection);
/// assert!(json.is_err());
/// assert!(json.is_err())
///
/// # Ok(())
/// # }
Expand Down Expand Up @@ -1992,3 +1992,100 @@ define_sql_function! {
/// ```
fn jsonb_strip_nulls<E: JsonbOrNullableJsonb + SingleValue>(jsonb: E) -> E;
}

#[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 @@ -517,3 +517,15 @@ pub type json_strip_nulls<E> = super::functions::json_strip_nulls<SqlTypeOf<E>,
#[allow(non_camel_case_types)]
#[cfg(feature = "postgres_backend")]
pub type jsonb_strip_nulls<E> = super::functions::jsonb_strip_nulls<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 @@ -444,6 +445,13 @@ fn postgres_functions() -> _ {
jsonb_pretty(pg_extras::jsonb),
json_strip_nulls(pg_extras::json),
jsonb_strip_nulls(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 2a9e3df

Please sign in to comment.