Skip to content

Commit c5cdaa4

Browse files
mertwoleweiznich
authored andcommitted
feat(sqlite): Add json_group_array and jsonb_group_array functions
1 parent 1712c60 commit c5cdaa4

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

diesel/src/sqlite/expression/functions.rs

+74
Original file line numberDiff line numberDiff line change
@@ -959,4 +959,78 @@ extern "SQL" {
959959
#[sql_name = "json_quote"]
960960
#[cfg(feature = "sqlite")]
961961
fn json_quote<J: SqlType + SingleValue>(j: J) -> Json;
962+
963+
/// The `json_group_array(X)` function is an aggregate SQL function that returns a JSON array comprised of
964+
/// all X values in the aggregation.
965+
///
966+
/// # Examples
967+
///
968+
/// ```rust
969+
/// # include!("../../doctest_setup.rs");
970+
/// #
971+
/// # fn main() {
972+
/// # #[cfg(feature = "serde_json")]
973+
/// # run_test().unwrap();
974+
/// # }
975+
/// #
976+
/// # #[cfg(feature = "serde_json")]
977+
/// # fn run_test() -> QueryResult<()> {
978+
/// # use diesel::dsl::*;
979+
/// # use schema::animals::dsl::*;
980+
/// # use serde_json::json;
981+
/// #
982+
/// # let connection = &mut establish_connection();
983+
/// #
984+
/// let result = animals.select(json_group_array(species)).get_result::<serde_json::Value>(connection)?;
985+
/// assert_eq!(result, json!(["dog", "spider"]));
986+
///
987+
/// let result = animals.select(json_group_array(legs)).get_result::<serde_json::Value>(connection)?;
988+
/// assert_eq!(result, json!([4, 8]));
989+
///
990+
/// let result = animals.select(json_group_array(name)).get_result::<serde_json::Value>(connection)?;
991+
/// assert_eq!(result, json!(["Jack", null]));
992+
///
993+
/// # Ok(())
994+
/// # }
995+
/// ```
996+
#[cfg(feature = "sqlite")]
997+
#[aggregate]
998+
fn json_group_array<E: SqlType + SingleValue>(elements: E) -> Json;
999+
1000+
/// The `jsonb_group_array(X)` function is an aggregate SQL function that returns a JSONB array comprised of
1001+
/// all X values in the aggregation.
1002+
///
1003+
/// # Examples
1004+
///
1005+
/// ```rust
1006+
/// # include!("../../doctest_setup.rs");
1007+
/// #
1008+
/// # fn main() {
1009+
/// # #[cfg(feature = "serde_json")]
1010+
/// # run_test().unwrap();
1011+
/// # }
1012+
/// #
1013+
/// # #[cfg(feature = "serde_json")]
1014+
/// # fn run_test() -> QueryResult<()> {
1015+
/// # use diesel::dsl::*;
1016+
/// # use schema::animals::dsl::*;
1017+
/// # use serde_json::json;
1018+
/// #
1019+
/// # let connection = &mut establish_connection();
1020+
/// #
1021+
/// let result = animals.select(json_group_array(species)).get_result::<serde_json::Value>(connection)?;
1022+
/// assert_eq!(result, json!(["dog", "spider"]));
1023+
///
1024+
/// let result = animals.select(json_group_array(legs)).get_result::<serde_json::Value>(connection)?;
1025+
/// assert_eq!(result, json!([4, 8]));
1026+
///
1027+
/// let result = animals.select(json_group_array(name)).get_result::<serde_json::Value>(connection)?;
1028+
/// assert_eq!(result, json!(["Jack", null]));
1029+
///
1030+
/// # Ok(())
1031+
/// # }
1032+
/// ```
1033+
#[cfg(feature = "sqlite")]
1034+
#[aggregate]
1035+
fn jsonb_group_array<E: SqlType + SingleValue>(elements: E) -> Jsonb;
9621036
}

diesel/src/sqlite/expression/helper_types.rs

+10
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,13 @@ pub type json_type_with_path<J, P> = super::functions::json_type_with_path<SqlTy
6363
#[allow(non_camel_case_types)]
6464
#[cfg(feature = "sqlite")]
6565
pub type json_quote<J> = super::functions::json_quote<SqlTypeOf<J>, J>;
66+
67+
/// Return type of [`json_group_array(value)`](super::functions::json_group_array())
68+
#[allow(non_camel_case_types)]
69+
#[cfg(feature = "sqlite")]
70+
pub type json_group_array<E> = super::functions::json_group_array<SqlTypeOf<E>, E>;
71+
72+
/// Return type of [`jsonb_group_array(value)`](super::functions::jsonb_group_array())
73+
#[allow(non_camel_case_types)]
74+
#[cfg(feature = "sqlite")]
75+
pub type jsonb_group_array<E> = super::functions::jsonb_group_array<SqlTypeOf<E>, E>;

diesel_derives/tests/auto_type.rs

+11
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,17 @@ fn sqlite_functions() -> _ {
520520
)
521521
}
522522

523+
#[cfg(feature = "sqlite")]
524+
#[auto_type]
525+
fn sqlite_aggregate_functions() -> _ {
526+
(
527+
json_group_array(users::name),
528+
json_group_array(users::id),
529+
jsonb_group_array(users::name),
530+
jsonb_group_array(users::id),
531+
)
532+
}
533+
523534
#[auto_type]
524535
fn with_lifetime<'a>(name: &'a str) -> _ {
525536
users::table.filter(users::name.eq(name))

0 commit comments

Comments
 (0)