surrealpatch/src/net/key.rs

321 lines
9.3 KiB
Rust
Raw Normal View History

use crate::dbs::Session;
use crate::err::Error;
2022-02-09 15:55:04 +00:00
use crate::net::conf;
use crate::net::head;
use crate::net::output;
use crate::net::DB;
use crate::sql::value::Value;
use bytes::Bytes;
2020-06-29 15:36:01 +00:00
use serde::Deserialize;
2021-03-29 15:43:37 +00:00
use std::str;
2020-06-29 15:36:01 +00:00
use warp::path;
use warp::Filter;
#[derive(Default, Deserialize, Debug, Clone)]
pub struct Query {
pub limit: Option<String>,
pub start: Option<String>,
}
pub fn config() -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
// ------------------------------
// Routes for OPTIONS
// ------------------------------
2020-06-29 15:36:01 +00:00
let base = warp::path("key");
// Set opts method
let opts = base.and(warp::options()).map(warp::reply);
// ------------------------------
// Routes for a table
// ------------------------------
// All methods
let base = warp::any();
// Get session config
let base = base.and(conf::build());
2022-01-14 17:13:44 +00:00
// Get content type header
let base = base.and(warp::header::<String>(http::header::CONTENT_TYPE.as_str()));
2020-06-29 15:36:01 +00:00
// Set base path for all
let base = base.and(path!("key" / String).and(warp::path::end()));
2020-06-29 15:36:01 +00:00
// Set select method
let select = base.and(warp::get()).and(warp::query()).and_then(select_all);
// Set create method
let create = base
.and(warp::post())
.and(warp::body::content_length_limit(1024 * 1024 * 1)) // 1MiB
2020-06-29 15:36:01 +00:00
.and(warp::body::bytes())
.and_then(create_all);
// Set delete method
let delete = base.and(warp::delete()).and_then(delete_all);
// Specify route
let all = select.or(create).or(delete);
// ------------------------------
// Routes for a thing
// ------------------------------
// All methods
let base = warp::any();
// Get session config
let base = base.and(conf::build());
2022-01-14 17:13:44 +00:00
// Get content type header
let base = base.and(warp::header::<String>(http::header::CONTENT_TYPE.as_str()));
2020-06-29 15:36:01 +00:00
// Set base path for one
let base = base.and(path!("key" / String / String).and(warp::path::end()));
2020-06-29 15:36:01 +00:00
// Set select method
let select = base.and(warp::get()).and_then(select_one);
// Set create method
let create = base
.and(warp::post())
.and(warp::body::content_length_limit(1024 * 1024 * 1)) // 1MiB
2020-06-29 15:36:01 +00:00
.and(warp::body::bytes())
.and_then(create_one);
// Set update method
let update = base
.and(warp::put())
.and(warp::body::content_length_limit(1024 * 1024 * 1)) // 1MiB
2020-06-29 15:36:01 +00:00
.and(warp::body::bytes())
.and_then(update_one);
// Set modify method
let modify = base
.and(warp::patch())
.and(warp::body::content_length_limit(1024 * 1024 * 1)) // 1MiB
2020-06-29 15:36:01 +00:00
.and(warp::body::bytes())
.and_then(modify_one);
// Set delete method
let delete = base.and(warp::delete()).and_then(delete_one);
// Specify route
let one = select.or(create).or(update).or(modify).or(delete);
// ------------------------------
// All routes
// ------------------------------
// Specify route
opts.or(all).or(one).with(head::cors())
}
// ------------------------------
// Routes for a table
// ------------------------------
async fn select_all(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
table: String,
query: Query,
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
2020-06-29 15:36:01 +00:00
let sql = format!(
2021-03-29 15:43:37 +00:00
"SELECT * FROM type::table($table) LIMIT {l} START {s}",
2020-06-29 15:36:01 +00:00
l = query.limit.unwrap_or(String::from("100")),
s = query.start.unwrap_or(String::from("0")),
);
2022-02-09 15:55:04 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
};
match crate::dbs::execute(db, sql.as_str(), session, Some(vars)).await {
Ok(ref res) => match output.as_ref() {
"application/json" => Ok(output::json(res)),
"application/cbor" => Ok(output::cbor(res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
2020-06-29 15:36:01 +00:00
}
async fn create_all(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
2020-06-29 15:36:01 +00:00
table: String,
body: Bytes,
2020-06-29 15:36:01 +00:00
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
let data = str::from_utf8(&body).unwrap();
match crate::sql::value::json(data) {
Ok((_, data)) => {
let sql = "CREATE type::table($table) CONTENT $data";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("data") => Value::from(data),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
}
Err(_) => Err(warp::reject::custom(Error::RequestError)),
}
2020-06-29 15:36:01 +00:00
}
2022-01-14 17:13:44 +00:00
async fn delete_all(
session: Session,
output: String,
table: String,
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
2021-03-29 15:43:37 +00:00
let sql = "DELETE type::table($table)";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
2020-06-29 15:36:01 +00:00
}
// ------------------------------
// Routes for a thing
// ------------------------------
async fn select_one(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
table: String,
id: String,
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
2021-03-29 15:43:37 +00:00
let sql = "SELECT * FROM type::thing($table, $id)";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("id") => Value::from(id),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
2020-06-29 15:36:01 +00:00
}
async fn create_one(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
2020-06-29 15:36:01 +00:00
table: String,
id: String,
body: Bytes,
2020-06-29 15:36:01 +00:00
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
let data = str::from_utf8(&body).unwrap();
match crate::sql::value::json(data) {
Ok((_, data)) => {
let sql = "CREATE type::thing($table, $id) CONTENT $data";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("id") => Value::from(id),
String::from("data") => Value::from(data),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
}
Err(_) => Err(warp::reject::custom(Error::RequestError)),
}
2020-06-29 15:36:01 +00:00
}
async fn update_one(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
2020-06-29 15:36:01 +00:00
table: String,
id: String,
body: Bytes,
2020-06-29 15:36:01 +00:00
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
let data = str::from_utf8(&body).unwrap();
match crate::sql::value::json(data) {
Ok((_, data)) => {
let sql = "UPDATE type::thing($table, $id) CONTENT $data";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("id") => Value::from(id),
String::from("data") => Value::from(data),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
}
Err(_) => Err(warp::reject::custom(Error::RequestError)),
}
2020-06-29 15:36:01 +00:00
}
async fn modify_one(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
2020-06-29 15:36:01 +00:00
table: String,
id: String,
body: Bytes,
2020-06-29 15:36:01 +00:00
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
let data = str::from_utf8(&body).unwrap();
match crate::sql::value::json(data) {
Ok((_, data)) => {
let sql = "UPDATE type::thing($table, $id) MERGE $data";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("id") => Value::from(id),
String::from("data") => Value::from(data),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
}
Err(_) => Err(warp::reject::custom(Error::RequestError)),
}
2020-06-29 15:36:01 +00:00
}
async fn delete_one(
session: Session,
2022-01-14 17:13:44 +00:00
output: String,
table: String,
id: String,
) -> Result<impl warp::Reply, warp::Rejection> {
let db = DB.get().unwrap().clone();
2021-03-29 15:43:37 +00:00
let sql = "DELETE type::thing($table, $id)";
2022-02-13 23:37:30 +00:00
let vars = hmap! {
String::from("table") => Value::from(table),
String::from("id") => Value::from(id),
};
match crate::dbs::execute(db, sql, session, Some(vars)).await {
2022-01-14 17:13:44 +00:00
Ok(res) => match output.as_ref() {
"application/json" => Ok(output::json(&res)),
"application/cbor" => Ok(output::cbor(&res)),
"application/msgpack" => Ok(output::pack(&res)),
2022-01-14 17:13:44 +00:00
_ => Err(warp::reject::not_found()),
},
Err(err) => Err(warp::reject::custom(err)),
}
2020-06-29 15:36:01 +00:00
}