Skip to content

Commit fd9feab

Browse files
authored
Merge pull request #9 from supabase/feature/rpc
Add support for rpc and switching schema
2 parents 5edf4e2 + 262c942 commit fd9feab

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

rustfmt.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"edition" = "2018"

src/builder.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,29 @@ macro_rules! filter {
1212
}
1313
}
1414

15+
#[derive(Default)]
1516
pub struct Builder {
1617
method: Method,
1718
url: String,
19+
schema: Option<String>,
1820
queries: Vec<(String, String)>,
21+
// TODO: Maybe change to HeaderMap in the future
1922
headers: Vec<(String, String)>,
2023
body: Option<String>,
24+
is_rpc: bool,
2125
}
2226

2327
// TODO: Complex filters (not, and, or)
24-
// TODO: Switching schema
2528
// TODO: Exact, planned, estimated count (HEAD verb)
2629
// TODO: Response format
2730
// TODO: Embedded resources
2831
impl Builder {
29-
pub fn new(url: &str) -> Self {
32+
pub fn new(url: &str, schema: Option<String>) -> Self {
3033
Builder {
3134
method: Method::GET,
3235
url: url.to_string(),
33-
queries: Vec::new(),
34-
headers: Vec::new(),
35-
body: None,
36+
schema,
37+
..Default::default()
3638
}
3739
}
3840

@@ -96,6 +98,7 @@ impl Builder {
9698
self.method = Method::POST;
9799
self.headers.push((
98100
"Prefer".to_string(),
101+
// Maybe check if this works as intended...
99102
"return=representation; resolution=merge-duplicates".to_string(),
100103
));
101104
self.body = Some(body.to_string());
@@ -127,21 +130,38 @@ impl Builder {
127130
self
128131
}
129132

130-
pub fn in_set(mut self, column: &str, param: &str) -> Self {
131-
self.queries
132-
.push((column.to_string(), format!("in.{}", param)));
133-
self
134-
}
135-
136133
// It's unfortunate that `in` is a keyword, otherwise it'd belong in the
137134
// collection of filters below
138135
filter!(
139136
eq, gt, gte, lt, lte, neq, like, ilike, is, fts, plfts, phfts, wfts, cs, cd, ov, sl, sr,
140137
nxr, nxl, adj, not
141138
);
142139

140+
pub fn in_(mut self, column: &str, param: &str) -> Self {
141+
self.queries
142+
.push((column.to_string(), format!("in.{}", param)));
143+
self
144+
}
145+
146+
pub fn rpc(mut self, params: &str) -> Self {
147+
self.method = Method::POST;
148+
self.body = Some(params.to_string());
149+
self.is_rpc = true;
150+
self
151+
}
152+
143153
pub async fn execute(self) -> Result<Response, Error> {
144-
let mut req = Client::new().request(self.method, &self.url);
154+
let mut req = Client::new().request(self.method.clone(), &self.url);
155+
if let Some(schema) = self.schema {
156+
// NOTE: Upstream bug: RPC only works with Accept-Profile
157+
// Will change when upstream is fixed
158+
let key = if !self.is_rpc || self.method == Method::GET || self.method == Method::HEAD {
159+
"Accept-Profile"
160+
} else {
161+
"Content-Profile"
162+
};
163+
req = req.header(key, schema);
164+
}
145165
for (k, v) in &self.headers {
146166
req = req.header(k, v);
147167
}

src/lib.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
use builder::Builder;
2-
31
mod builder;
42

3+
use builder::Builder;
4+
55
pub struct Postgrest {
6-
rest_url: String,
6+
url: String,
7+
schema: Option<String>,
78
}
89

910
impl Postgrest {
10-
pub fn new(rest_url: &str) -> Postgrest {
11+
pub fn new(url: &str) -> Self {
1112
Postgrest {
12-
rest_url: rest_url.to_string(),
13+
url: url.to_string(),
14+
schema: None,
1315
}
1416
}
1517

18+
pub fn schema(mut self, schema: &str) -> Self {
19+
self.schema = Some(schema.to_string());
20+
self
21+
}
22+
1623
pub fn from(&self, table: &str) -> Builder {
17-
let mut url = self.rest_url.clone();
18-
url = format!("{}/{}", url, table);
19-
Builder::new(&url)
24+
let url = format!("{}/{}", self.url, table);
25+
Builder::new(&url, self.schema.clone())
26+
}
27+
28+
pub fn rpc(&self, function: &str, params: &str) -> Builder {
29+
let url = format!("{}/rpc/{}", self.url, function);
30+
Builder::new(&url, self.schema.clone()).rpc(params)
2031
}
2132
}

0 commit comments

Comments
 (0)