supabase_client_query/
insert.rs1use std::marker::PhantomData;
2
3use serde::de::DeserializeOwned;
4
5use supabase_client_core::SupabaseResponse;
6
7use crate::backend::QueryBackend;
8use crate::modifier::Modifiable;
9use crate::sql::{ParamStore, SqlParts};
10
11pub struct InsertBuilder<T> {
14 pub(crate) backend: QueryBackend,
15 pub(crate) parts: SqlParts,
16 pub(crate) params: ParamStore,
17 pub(crate) _marker: PhantomData<T>,
18}
19
20impl<T> Modifiable for InsertBuilder<T> {
21 fn parts_mut(&mut self) -> &mut SqlParts {
22 &mut self.parts
23 }
24}
25
26impl<T> InsertBuilder<T> {
27 pub fn schema(mut self, schema: &str) -> Self {
31 self.parts.schema_override = Some(schema.to_string());
32 self
33 }
34
35 pub fn select(mut self) -> Self {
37 self.parts.returning = Some("*".to_string());
38 self
39 }
40
41 pub fn select_columns(mut self, columns: &str) -> Self {
43 if columns == "*" || columns.is_empty() {
44 self.parts.returning = Some("*".to_string());
45 } else {
46 let quoted = columns
47 .split(',')
48 .map(|c| {
49 let c = c.trim();
50 if c.contains('(') || c.contains('*') || c.contains('"') {
51 c.to_string()
52 } else {
53 format!("\"{}\"", c)
54 }
55 })
56 .collect::<Vec<_>>()
57 .join(", ");
58 self.parts.returning = Some(quoted);
59 }
60 self
61 }
62}
63
64#[cfg(not(feature = "direct-sql"))]
66impl<T> InsertBuilder<T>
67where
68 T: DeserializeOwned + Send,
69{
70 pub async fn execute(self) -> SupabaseResponse<T> {
72 let QueryBackend::Rest { ref http, ref base_url, ref api_key, ref schema } = self.backend;
73 let (url, headers, body) = match crate::postgrest::build_postgrest_insert(
74 base_url, &self.parts, &self.params,
75 ) {
76 Ok(r) => r,
77 Err(e) => return SupabaseResponse::error(
78 supabase_client_core::SupabaseError::QueryBuilder(e),
79 ),
80 };
81 crate::postgrest_execute::execute_rest(
82 http, reqwest::Method::POST, &url, headers, Some(body), api_key, schema, &self.parts,
83 ).await
84 }
85}
86
87#[cfg(feature = "direct-sql")]
89impl<T> InsertBuilder<T>
90where
91 T: DeserializeOwned + Send + Unpin + for<'r> sqlx::FromRow<'r, sqlx::postgres::PgRow>,
92{
93 pub async fn execute(self) -> SupabaseResponse<T> {
95 match &self.backend {
96 QueryBackend::Rest { http, base_url, api_key, schema } => {
97 let (url, headers, body) = match crate::postgrest::build_postgrest_insert(
98 base_url, &self.parts, &self.params,
99 ) {
100 Ok(r) => r,
101 Err(e) => return SupabaseResponse::error(
102 supabase_client_core::SupabaseError::QueryBuilder(e),
103 ),
104 };
105 crate::postgrest_execute::execute_rest(
106 http, reqwest::Method::POST, &url, headers, Some(body), api_key, schema, &self.parts,
107 ).await
108 }
109 QueryBackend::DirectSql { pool } => {
110 crate::execute::execute_typed::<T>(pool, &self.parts, &self.params).await
111 }
112 }
113 }
114}