Add support for SQL parameters in HTTP REST endpoints
This commit is contained in:
parent
c63fc47bc0
commit
7ed0af4750
4 changed files with 48 additions and 1 deletions
|
@ -2,6 +2,7 @@ use crate::cli::CF;
|
||||||
use crate::dbs::DB;
|
use crate::dbs::DB;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::net::output;
|
use crate::net::output;
|
||||||
|
use crate::net::params::Params;
|
||||||
use crate::net::session;
|
use crate::net::session;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -47,6 +48,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(path!("key" / String).and(warp::path::end()))
|
.and(path!("key" / String).and(warp::path::end()))
|
||||||
.and(warp::body::content_length_limit(MAX))
|
.and(warp::body::content_length_limit(MAX))
|
||||||
.and(warp::body::bytes())
|
.and(warp::body::bytes())
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(create_all);
|
.and_then(create_all);
|
||||||
// Set delete method
|
// Set delete method
|
||||||
|
@ -54,6 +56,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(warp::delete())
|
.and(warp::delete())
|
||||||
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
||||||
.and(path!("key" / String).and(warp::path::end()))
|
.and(path!("key" / String).and(warp::path::end()))
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(delete_all);
|
.and_then(delete_all);
|
||||||
// Specify route
|
// Specify route
|
||||||
|
@ -77,6 +80,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(path!("key" / String / String).and(warp::path::end()))
|
.and(path!("key" / String / String).and(warp::path::end()))
|
||||||
.and(warp::body::content_length_limit(MAX))
|
.and(warp::body::content_length_limit(MAX))
|
||||||
.and(warp::body::bytes())
|
.and(warp::body::bytes())
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(create_one);
|
.and_then(create_one);
|
||||||
// Set update method
|
// Set update method
|
||||||
|
@ -86,6 +90,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(path!("key" / String / String).and(warp::path::end()))
|
.and(path!("key" / String / String).and(warp::path::end()))
|
||||||
.and(warp::body::content_length_limit(MAX))
|
.and(warp::body::content_length_limit(MAX))
|
||||||
.and(warp::body::bytes())
|
.and(warp::body::bytes())
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(update_one);
|
.and_then(update_one);
|
||||||
// Set modify method
|
// Set modify method
|
||||||
|
@ -95,6 +100,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(path!("key" / String / String).and(warp::path::end()))
|
.and(path!("key" / String / String).and(warp::path::end()))
|
||||||
.and(warp::body::content_length_limit(MAX))
|
.and(warp::body::content_length_limit(MAX))
|
||||||
.and(warp::body::bytes())
|
.and(warp::body::bytes())
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(modify_one);
|
.and_then(modify_one);
|
||||||
// Set delete method
|
// Set delete method
|
||||||
|
@ -102,6 +108,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(warp::delete())
|
.and(warp::delete())
|
||||||
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
||||||
.and(path!("key" / String / String).and(warp::path::end()))
|
.and(path!("key" / String / String).and(warp::path::end()))
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(delete_one);
|
.and_then(delete_one);
|
||||||
// Specify route
|
// Specify route
|
||||||
|
@ -157,6 +164,7 @@ async fn create_all(
|
||||||
output: String,
|
output: String,
|
||||||
table: String,
|
table: String,
|
||||||
body: Bytes,
|
body: Bytes,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -174,6 +182,7 @@ async fn create_all(
|
||||||
let vars = map! {
|
let vars = map! {
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
String::from("data") => data,
|
String::from("data") => data,
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
@ -195,6 +204,7 @@ async fn create_all(
|
||||||
async fn delete_all(
|
async fn delete_all(
|
||||||
output: String,
|
output: String,
|
||||||
table: String,
|
table: String,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -206,6 +216,7 @@ async fn delete_all(
|
||||||
// Specify the request variables
|
// Specify the request variables
|
||||||
let vars = map! {
|
let vars = map! {
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
@ -266,6 +277,7 @@ async fn create_one(
|
||||||
table: String,
|
table: String,
|
||||||
id: String,
|
id: String,
|
||||||
body: Bytes,
|
body: Bytes,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -289,6 +301,7 @@ async fn create_one(
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
String::from("id") => rid,
|
String::from("id") => rid,
|
||||||
String::from("data") => data,
|
String::from("data") => data,
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
@ -312,6 +325,7 @@ async fn update_one(
|
||||||
table: String,
|
table: String,
|
||||||
id: String,
|
id: String,
|
||||||
body: Bytes,
|
body: Bytes,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -335,6 +349,7 @@ async fn update_one(
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
String::from("id") => rid,
|
String::from("id") => rid,
|
||||||
String::from("data") => data,
|
String::from("data") => data,
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
@ -358,6 +373,7 @@ async fn modify_one(
|
||||||
table: String,
|
table: String,
|
||||||
id: String,
|
id: String,
|
||||||
body: Bytes,
|
body: Bytes,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -381,6 +397,7 @@ async fn modify_one(
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
String::from("id") => rid,
|
String::from("id") => rid,
|
||||||
String::from("data") => data,
|
String::from("data") => data,
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
@ -403,6 +420,7 @@ async fn delete_one(
|
||||||
output: String,
|
output: String,
|
||||||
table: String,
|
table: String,
|
||||||
id: String,
|
id: String,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get the datastore reference
|
// Get the datastore reference
|
||||||
|
@ -420,6 +438,7 @@ async fn delete_one(
|
||||||
let vars = map! {
|
let vars = map! {
|
||||||
String::from("table") => Value::from(table),
|
String::from("table") => Value::from(table),
|
||||||
String::from("id") => rid,
|
String::from("id") => rid,
|
||||||
|
=> params.parse()
|
||||||
};
|
};
|
||||||
// Execute the query and return the result
|
// Execute the query and return the result
|
||||||
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
match db.execute(sql, &session, Some(vars), opt.strict).await {
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod index;
|
||||||
mod key;
|
mod key;
|
||||||
mod log;
|
mod log;
|
||||||
mod output;
|
mod output;
|
||||||
|
mod params;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
mod session;
|
mod session;
|
||||||
mod signin;
|
mod signin;
|
||||||
|
|
24
src/net/params.rs
Normal file
24
src/net/params.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use surrealdb::sql::Value;
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Params {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub inner: BTreeMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Params {
|
||||||
|
pub fn parse(self) -> BTreeMap<String, Value> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Params> for BTreeMap<String, Value> {
|
||||||
|
fn from(v: Params) -> BTreeMap<String, Value> {
|
||||||
|
v.inner
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, v)| (k, surrealdb::sql::json(&v).unwrap_or_else(|_| Value::from(v))))
|
||||||
|
.collect::<BTreeMap<_, _>>()
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use crate::cli::CF;
|
||||||
use crate::dbs::DB;
|
use crate::dbs::DB;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::net::output;
|
use crate::net::output;
|
||||||
|
use crate::net::params::Params;
|
||||||
use crate::net::session;
|
use crate::net::session;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
|
@ -22,6 +23,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
.and(warp::header::<String>(http::header::ACCEPT.as_str()))
|
||||||
.and(warp::body::content_length_limit(MAX))
|
.and(warp::body::content_length_limit(MAX))
|
||||||
.and(warp::body::bytes())
|
.and(warp::body::bytes())
|
||||||
|
.and(warp::query())
|
||||||
.and(session::build())
|
.and(session::build())
|
||||||
.and_then(handler);
|
.and_then(handler);
|
||||||
// Set sock method
|
// Set sock method
|
||||||
|
@ -36,6 +38,7 @@ pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejecti
|
||||||
async fn handler(
|
async fn handler(
|
||||||
output: String,
|
output: String,
|
||||||
sql: Bytes,
|
sql: Bytes,
|
||||||
|
params: Params,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
|
@ -45,7 +48,7 @@ async fn handler(
|
||||||
// Convert the received sql query
|
// Convert the received sql query
|
||||||
let sql = std::str::from_utf8(&sql).unwrap();
|
let sql = std::str::from_utf8(&sql).unwrap();
|
||||||
// Execute the received sql query
|
// Execute the received sql query
|
||||||
match db.execute(sql, &session, None, opt.strict).await {
|
match db.execute(sql, &session, params.parse().into(), opt.strict).await {
|
||||||
// Convert the response to JSON
|
// Convert the response to JSON
|
||||||
Ok(res) => match output.as_ref() {
|
Ok(res) => match output.as_ref() {
|
||||||
"application/json" => Ok(output::json(&res)),
|
"application/json" => Ok(output::json(&res)),
|
||||||
|
|
Loading…
Reference in a new issue