Rewrite create_index route new path, body request and response

This commit is contained in:
Quentin de Quelen 2019-11-19 16:07:24 +01:00
parent 076e781810
commit 5527457655
2 changed files with 62 additions and 24 deletions

View File

@ -1,9 +1,12 @@
use meilidb_schema::Schema;
use http::StatusCode; use http::StatusCode;
use meilidb_core::ProcessedUpdateResult; use meilidb_core::ProcessedUpdateResult;
use meilidb_schema::Schema; use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
use tide::response::IntoResponse; use tide::response::IntoResponse;
use tide::{Context, Response}; use tide::{Context, Response};
use chrono::{DateTime, Utc};
use crate::error::{ResponseError, SResult}; use crate::error::{ResponseError, SResult};
use crate::helpers::tide::ContextExt; use crate::helpers::tide::ContextExt;
@ -12,6 +15,15 @@ use crate::models::token::ACL::*;
use crate::routes::document::IndexUpdateResponse; use crate::routes::document::IndexUpdateResponse;
use crate::Data; use crate::Data;
fn generate_uid() -> String {
let mut rng = rand::thread_rng();
let sample = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
sample
.choose_multiple(&mut rng, 8)
.map(|c| *c as char)
.collect()
}
pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> { pub async fn list_indexes(ctx: Context<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesRead)?; ctx.is_allowed(IndexesRead)?;
let list = ctx let list = ctx
@ -48,23 +60,34 @@ pub async fn get_index_schema(ctx: Context<Data>) -> SResult<Response> {
} }
} }
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct IndexCreateRequest {
name: String,
schema: Option<SchemaBody>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct IndexCreateResponse {
name: String,
uid: String,
schema: Option<SchemaBody>,
update_id: Option<u64>,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
}
pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> { pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
ctx.is_allowed(IndexesWrite)?; ctx.is_allowed(IndexesWrite)?;
let index_name = ctx.url_param("index")?; let body = ctx.body_json::<IndexCreateRequest>().await.map_err(ResponseError::bad_request)?;
let body = ctx.body_bytes().await.map_err(ResponseError::bad_request)?; let generated_uid = generate_uid();
let schema: Option<Schema> = if body.is_empty() {
None
} else {
serde_json::from_slice::<SchemaBody>(&body)
.map_err(ResponseError::bad_request)
.map(|s| Some(s.into()))?
};
let db = &ctx.state().db; let db = &ctx.state().db;
let created_index = match db.create_index(&index_name) { let created_index = match db.create_index(&generated_uid) {
Ok(index) => index, Ok(index) => index,
Err(e) => return Err(ResponseError::create_index(e)), Err(e) => return Err(ResponseError::create_index(e)),
}; };
@ -72,23 +95,37 @@ pub async fn create_index(mut ctx: Context<Data>) -> SResult<Response> {
let env = &db.env; let env = &db.env;
let mut writer = env.write_txn().map_err(ResponseError::internal)?; let mut writer = env.write_txn().map_err(ResponseError::internal)?;
match schema { created_index.main
Some(schema) => { .put_name(&mut writer, &body.name)
.map_err(ResponseError::internal)?;
created_index.main
.put_created_at(&mut writer)
.map_err(ResponseError::internal)?;
created_index.main
let schema: Option<Schema> = body.schema.clone().map(|s| s.into());
let mut response_update_id = None;
if let Some(schema) = schema {
let update_id = created_index let update_id = created_index
.schema_update(&mut writer, schema.clone()) .schema_update(&mut writer, schema.clone())
.map_err(ResponseError::internal)?; .map_err(ResponseError::internal)?;
response_update_id = Some(update_id)
}
writer.commit().map_err(ResponseError::internal)?; writer.commit().map_err(ResponseError::internal)?;
let response_body = IndexUpdateResponse { update_id }; let response_body = IndexCreateResponse {
name: body.name,
uid: generated_uid,
schema: body.schema,
update_id: response_update_id,
created_at: Utc::now(),
updated_at: Utc::now(),
};
Ok(tide::response::json(response_body) Ok(tide::response::json(response_body)
.with_status(StatusCode::CREATED) .with_status(StatusCode::CREATED)
.into_response()) .into_response())
}
None => Ok(Response::new(tide::Body::empty())
.with_status(StatusCode::NO_CONTENT)
.into_response()),
}
} }
pub async fn update_schema(mut ctx: Context<Data>) -> SResult<Response> { pub async fn update_schema(mut ctx: Context<Data>) -> SResult<Response> {

View File

@ -13,7 +13,9 @@ pub mod synonym;
pub fn load_routes(app: &mut tide::App<Data>) { pub fn load_routes(app: &mut tide::App<Data>) {
app.at("").nest(|router| { app.at("").nest(|router| {
router.at("/indexes").nest(|router| { router.at("/indexes").nest(|router| {
router.at("/").get(index::list_indexes); router.at("/")
.get(index::list_indexes)
.post(index::create_index);
router.at("/search").post(search::search_multi_index); router.at("/search").post(search::search_multi_index);
@ -29,7 +31,6 @@ pub fn load_routes(app: &mut tide::App<Data>) {
router router
.at("/") .at("/")
.get(index::get_index_schema) .get(index::get_index_schema)
.post(index::create_index)
.put(index::update_schema) .put(index::update_schema)
.delete(index::delete_index); .delete(index::delete_index);