sea_query/extension/postgres/func/
json_value.rs1use std::borrow::Cow;
2
3use crate::{
4 extension::postgres::json_fn::{write_json_path_expr, write_passing},
5 *,
6};
7
8#[derive(Debug, Clone)]
9pub struct Builder {
10 context_item: Expr,
11 path_expression: Cow<'static, str>,
12 passing: Vec<(Value, Cow<'static, str>)>,
13 returning: Option<crate::TypeRef>,
14 on_empty: Option<OnClause>,
15 on_error: Option<OnClause>,
16}
17
18#[derive(Debug, Clone)]
19enum OnClause {
20 Error,
21 Null,
22 Default(Expr),
23}
24
25impl Builder {
26 pub fn passing<V, A>(mut self, value: V, alias: A) -> Self
27 where
28 V: Into<Value>,
29 A: Into<Cow<'static, str>>,
30 {
31 self.passing.push((value.into(), alias.into()));
32 self
33 }
34
35 pub fn passing_many<V, A, I>(mut self, passing: I) -> Self
37 where
38 V: Into<Value>,
39 A: Into<Cow<'static, str>>,
40 I: IntoIterator<Item = (V, A)>,
41 {
42 for (value, alias) in passing {
43 self.passing.push((value.into(), alias.into()));
44 }
45 self
46 }
47
48 pub fn returning<T>(mut self, returning: T) -> Self
50 where
51 T: Into<TypeRef>,
52 {
53 self.returning = Some(returning.into());
54 self
55 }
56
57 pub fn error_on_empty(mut self) -> Self {
59 self.on_empty = Some(OnClause::Error);
60 self
61 }
62
63 pub fn null_on_empty(mut self) -> Self {
65 self.on_empty = Some(OnClause::Null);
66 self
67 }
68
69 pub fn default_on_empty<T>(mut self, expr: T) -> Self
71 where
72 T: Into<Expr>,
73 {
74 self.on_empty = Some(OnClause::Default(expr.into()));
75 self
76 }
77
78 pub fn error_on_error(mut self) -> Self {
80 self.on_error = Some(OnClause::Error);
81 self
82 }
83
84 pub fn null_on_error(mut self) -> Self {
86 self.on_error = Some(OnClause::Null);
87 self
88 }
89
90 pub fn default_on_error<T>(mut self, expr: T) -> Self
92 where
93 T: Into<Expr>,
94 {
95 self.on_error = Some(OnClause::Default(expr.into()));
96 self
97 }
98
99 pub fn build(self) -> FunctionCall {
100 self.build_internal().unwrap()
101 }
102
103 fn build_internal(self) -> Result<FunctionCall, core::fmt::Error> {
104 let mut buf = String::with_capacity(50);
105
106 PostgresQueryBuilder.prepare_expr(&self.context_item, &mut buf);
107 buf.write_str(" ")?;
108 write_json_path_expr(&mut buf, &self.path_expression)?;
109
110 write_passing(&mut buf, self.passing)?;
111
112 if let Some(returning) = self.returning {
113 buf.write_str(" RETURNING ")?;
114
115 PostgresQueryBuilder.prepare_type_ref(&returning, &mut buf);
116 }
117
118 if let Some(on_empty) = self.on_empty {
119 match on_empty {
120 OnClause::Error => buf.write_str(" ERROR")?,
121 OnClause::Null => buf.write_str(" NULL")?,
122 OnClause::Default(expr) => {
123 buf.write_str(" DEFAULT ")?;
124 PostgresQueryBuilder.prepare_expr(&expr, &mut buf);
125 }
126 }
127 buf.write_str(" ON EMPTY")?;
128 }
129
130 if let Some(on_error) = self.on_error {
131 match on_error {
132 OnClause::Error => buf.write_str(" ERROR")?,
133 OnClause::Null => buf.write_str(" NULL")?,
134 OnClause::Default(expr) => {
135 buf.write_str(" DEFAULT ")?;
136 PostgresQueryBuilder.prepare_expr(&expr, &mut buf);
137 }
138 };
139 buf.write_str(" ON ERROR")?;
140 }
141
142 Ok(FunctionCall::new(Func::Custom("JSON_VALUE".into())).arg(Expr::Custom(buf.into())))
143 }
144}
145
146impl From<Builder> for FunctionCall {
147 fn from(builder: Builder) -> Self {
148 builder.build()
149 }
150}
151
152impl From<Builder> for Expr {
153 fn from(builder: Builder) -> Self {
154 Expr::FunctionCall(builder.build())
155 }
156}
157
158impl PgFunc {
159 pub fn json_value<T, P>(context_item: T, path_expression: P) -> Builder
218 where
219 T: Into<Expr>,
220 P: Into<Cow<'static, str>>,
221 {
222 Builder {
223 context_item: context_item.into(),
224 path_expression: path_expression.into(),
225 passing: Vec::new(),
226 returning: None,
227 on_empty: None,
228 on_error: None,
229 }
230 }
231}