Skip to content

Commit

Permalink
Add Postgres Json functions: JSON_BUILD_OBJECT and JSON_AGG (#787)
Browse files Browse the repository at this point in the history
* feat: add `json_build_object` function for postgres

* feat: add `json_agg` function for postgres

* style: add newlines

* chore: apply linting suggestions

* fix: tests for not_equals
  • Loading branch information
IgnisDa authored Sep 28, 2024
1 parent 2dba3c3 commit b001173
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/backend/postgres/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ impl QueryBuilder for PostgresQueryBuilder {
PgFunction::TsRankCd => "TS_RANK_CD",
PgFunction::StartsWith => "STARTS_WITH",
PgFunction::GenRandomUUID => "GEN_RANDOM_UUID",
PgFunction::JsonBuildObject => "JSON_BUILD_OBJECT",
PgFunction::JsonAgg => "JSON_AGG",
#[cfg(feature = "postgres-array")]
PgFunction::Any => "ANY",
#[cfg(feature = "postgres-array")]
Expand Down
8 changes: 4 additions & 4 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,20 +614,20 @@ impl Expr {
/// let query = Query::select()
/// .columns([Char::Character, Char::SizeW, Char::SizeH])
/// .from(Char::Table)
/// .and_where(Expr::col((Char::Table, Char::FontId)).equals((Font::Table, Font::Id)))
/// .and_where(Expr::col((Char::Table, Char::FontId)).not_equals((Font::Table, Font::Id)))
/// .to_owned();
///
/// assert_eq!(
/// query.to_string(MysqlQueryBuilder),
/// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`font_id` = `font`.`id`"#
/// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`font_id` <> `font`.`id`"#
/// );
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" = "font"."id""#
/// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" <> "font"."id""#
/// );
/// assert_eq!(
/// query.to_string(SqliteQueryBuilder),
/// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" = "font"."id""#
/// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."font_id" <> "font"."id""#
/// );
/// ```
pub fn not_equals<C>(self, col: C) -> SimpleExpr
Expand Down
57 changes: 57 additions & 0 deletions src/extension/postgres/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub enum PgFunction {
TsRankCd,
StartsWith,
GenRandomUUID,
JsonBuildObject,
JsonAgg,
#[cfg(feature = "postgres-array")]
Any,
#[cfg(feature = "postgres-array")]
Expand Down Expand Up @@ -350,4 +352,59 @@ impl PgFunc {
pub fn gen_random_uuid() -> FunctionCall {
FunctionCall::new(Function::PgFunction(PgFunction::GenRandomUUID))
}

/// Call the `JSON_BUILD_OBJECT` function. Postgres only.
///
/// # Examples
///
/// ```
/// use sea_query::{tests_cfg::*, *};
///
/// let query = Query::select()
/// .expr(PgFunc::json_build_object(vec![
/// (Expr::val("a"), Expr::val(1)),
/// (Expr::val("b"), Expr::val("2")),
/// ]))
/// .to_owned();
///
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT JSON_BUILD_OBJECT('a', 1, 'b', '2')"#
/// );
/// ```
pub fn json_build_object<T>(pairs: Vec<(T, T)>) -> FunctionCall
where
T: Into<SimpleExpr>,
{
let mut args = vec![];
for (key, value) in pairs {
args.push(key.into());
args.push(value.into());
}
FunctionCall::new(Function::PgFunction(PgFunction::JsonBuildObject)).args(args)
}

/// Call the `JSON_AGG` function. Postgres only.
///
/// # Examples
///
/// ```
/// use sea_query::{tests_cfg::*, *};
///
/// let query = Query::select()
/// .from(Char::Table)
/// .expr(PgFunc::json_agg(Expr::col(Char::SizeW)))
/// .to_owned();
///
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT JSON_AGG("size_w") FROM "character""#
/// );
/// ```
pub fn json_agg<T>(expr: T) -> FunctionCall
where
T: Into<SimpleExpr>,
{
FunctionCall::new(Function::PgFunction(PgFunction::JsonAgg)).arg(expr)
}
}

0 comments on commit b001173

Please sign in to comment.