diff --git a/meilidb-http/src/routes/index.rs b/meilidb-http/src/routes/index.rs index 0522d584f..e915a3573 100644 --- a/meilidb-http/src/routes/index.rs +++ b/meilidb-http/src/routes/index.rs @@ -1,9 +1,12 @@ +use meilidb_schema::Schema; use http::StatusCode; use meilidb_core::ProcessedUpdateResult; -use meilidb_schema::Schema; +use rand::seq::SliceRandom; +use serde::{Deserialize, Serialize}; use serde_json::json; use tide::response::IntoResponse; use tide::{Context, Response}; +use chrono::{DateTime, Utc}; use crate::error::{ResponseError, SResult}; use crate::helpers::tide::ContextExt; @@ -12,6 +15,15 @@ use crate::models::token::ACL::*; use crate::routes::document::IndexUpdateResponse; 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) -> SResult { ctx.is_allowed(IndexesRead)?; let list = ctx @@ -48,23 +60,34 @@ pub async fn get_index_schema(ctx: Context) -> SResult { } } +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct IndexCreateRequest { + name: String, + schema: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct IndexCreateResponse { + name: String, + uid: String, + schema: Option, + update_id: Option, + created_at: DateTime, + updated_at: DateTime, +} + pub async fn create_index(mut ctx: Context) -> SResult { ctx.is_allowed(IndexesWrite)?; - let index_name = ctx.url_param("index")?; + let body = ctx.body_json::().await.map_err(ResponseError::bad_request)?; - let body = ctx.body_bytes().await.map_err(ResponseError::bad_request)?; - let schema: Option = if body.is_empty() { - None - } else { - serde_json::from_slice::(&body) - .map_err(ResponseError::bad_request) - .map(|s| Some(s.into()))? - }; + let generated_uid = generate_uid(); 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, Err(e) => return Err(ResponseError::create_index(e)), }; @@ -72,23 +95,37 @@ pub async fn create_index(mut ctx: Context) -> SResult { let env = &db.env; let mut writer = env.write_txn().map_err(ResponseError::internal)?; - match schema { - Some(schema) => { - let update_id = created_index + created_index.main + .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 = body.schema.clone().map(|s| s.into()); + let mut response_update_id = None; + if let Some(schema) = schema { + let update_id = created_index .schema_update(&mut writer, schema.clone()) .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 }; - Ok(tide::response::json(response_body) + 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) .with_status(StatusCode::CREATED) .into_response()) - } - None => Ok(Response::new(tide::Body::empty()) - .with_status(StatusCode::NO_CONTENT) - .into_response()), - } } pub async fn update_schema(mut ctx: Context) -> SResult { diff --git a/meilidb-http/src/routes/mod.rs b/meilidb-http/src/routes/mod.rs index efcf5d4f4..c44134cc8 100644 --- a/meilidb-http/src/routes/mod.rs +++ b/meilidb-http/src/routes/mod.rs @@ -13,7 +13,9 @@ pub mod synonym; pub fn load_routes(app: &mut tide::App) { app.at("").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); @@ -29,7 +31,6 @@ pub fn load_routes(app: &mut tide::App) { router .at("/") .get(index::get_index_schema) - .post(index::create_index) .put(index::update_schema) .delete(index::delete_index);