simplify error handling by impl errors traits on ResponseError

This commit is contained in:
Quentin de Quelen 2020-04-17 14:52:13 +02:00 committed by qdequele
parent 4bd7e46ba6
commit e74d2c1872
No known key found for this signature in database
GPG key ID: B3F0A000EBF11745
10 changed files with 470 additions and 807 deletions

View file

@ -1,7 +1,5 @@
use std::collections::HashSet;
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashSet};
use actix_web as aweb;
use actix_web::{delete, get, post, put, web, HttpResponse};
use indexmap::IndexMap;
use serde::Deserialize;
@ -23,22 +21,18 @@ pub struct DocumentParam {
pub async fn get_document(
data: web::Data<Data>,
path: web::Path<DocumentParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let document_id = meilisearch_core::serde::compute_document_id(&path.document_id);
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let response = index
.document::<Document>(&reader, None, document_id)
.map_err(|_| ResponseError::DocumentNotFound(path.document_id.clone()))?
.ok_or(ResponseError::DocumentNotFound(path.document_id.clone()))?;
.document::<Document>(&reader, None, document_id)?
.ok_or(ResponseError::document_not_found(&path.document_id))?;
Ok(HttpResponse::Ok().json(response))
}
@ -47,28 +41,21 @@ pub async fn get_document(
pub async fn delete_document(
data: web::Data<Data>,
path: web::Path<DocumentParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let document_id = meilisearch_core::serde::compute_document_id(&path.document_id);
let mut update_writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut update_writer = data.db.update_write_txn()?;
let mut documents_deletion = index.documents_deletion();
documents_deletion.delete_document_by_id(document_id);
let update_id = documents_deletion
.finalize(&mut update_writer)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = documents_deletion.finalize(&mut update_writer)?;
update_writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
update_writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -86,32 +73,29 @@ pub async fn get_all_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
params: web::Query<BrowseQuery>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let offset = params.offset.unwrap_or(0);
let limit = params.limit.unwrap_or(20);
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let documents_ids: Result<BTreeSet<_>, _> = index
.documents_fields_counts
.documents_ids(&reader)
.map_err(|_| ResponseError::Internal(path.index_uid.clone()))?
.documents_ids(&reader)?
.skip(offset)
.take(limit)
.collect();
let documents_ids = documents_ids.map_err(|err| ResponseError::Internal(err.to_string()))?;
let documents_ids = documents_ids?;
let attributes: Option<HashSet<&str>> = params
.attributes_to_retrieve.as_ref()
.attributes_to_retrieve
.as_ref()
.map(|a| a.split(',').collect());
let mut response = Vec::<Document>::new();
@ -145,48 +129,33 @@ async fn update_multiple_documents(
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>,
is_partial: bool,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let mut schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to retrieve the schema".to_string(),
))?;
.schema(&reader)?
.ok_or(ResponseError::internal("Impossible to retrieve the schema"))?;
if schema.primary_key().is_none() {
let id = match params.primary_key.clone() {
Some(id) => id,
None => body.first().and_then(|docs| find_primary_key(docs)).ok_or(
ResponseError::BadRequest("Could not infer a primary key".to_string()),
)?,
let id = match &params.primary_key {
Some(id) => id.to_string(),
None => body
.first()
.and_then(find_primary_key)
.ok_or(ResponseError::bad_request("Could not infer a primary key"))?,
};
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.main_write_txn()?;
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
schema.set_primary_key(&id)?;
index.main.put_schema(&mut writer, &schema)?;
writer.commit()?;
}
let mut document_addition = if is_partial {
@ -199,16 +168,9 @@ async fn update_multiple_documents(
document_addition.update_document(document);
}
let mut update_writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = document_addition
.finalize(&mut update_writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
update_writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut update_writer = data.db.update_write_txn()?;
let update_id = document_addition.finalize(&mut update_writer)?;
update_writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -219,7 +181,7 @@ pub async fn add_documents(
path: web::Path<IndexParam>,
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
update_multiple_documents(data, path, params, body, false).await
}
@ -229,7 +191,7 @@ pub async fn update_documents(
path: web::Path<IndexParam>,
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
update_multiple_documents(data, path, params, body, true).await
}
@ -238,16 +200,13 @@ pub async fn delete_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Vec<Value>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let mut documents_deletion = index.documents_deletion();
@ -258,13 +217,9 @@ pub async fn delete_documents(
}
}
let update_id = documents_deletion
.finalize(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
let update_id = documents_deletion.finalize(&mut writer)?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -273,24 +228,17 @@ pub async fn delete_documents(
pub async fn clear_all_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index
.clear_all(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
let update_id = index.clear_all(&mut writer)?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}

View file

@ -1,6 +1,5 @@
use crate::error::ResponseError;
use crate::Data;
use actix_web as aweb;
use actix_web::{get, put, web, HttpResponse};
use heed::types::{Str, Unit};
use serde::Deserialize;
@ -8,49 +7,32 @@ use serde::Deserialize;
const UNHEALTHY_KEY: &str = "_is_unhealthy";
#[get("/health")]
pub async fn get_health(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
pub async fn get_health(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
let reader = data.db.main_read_txn()?;
let common_store = data.db.common_store();
if let Ok(Some(_)) = common_store.get::<_, Str, Unit>(&reader, UNHEALTHY_KEY) {
return Err(ResponseError::Maintenance.into());
return Err(ResponseError::Maintenance);
}
Ok(HttpResponse::Ok().finish())
}
pub async fn set_healthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
pub async fn set_healthy(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
let mut writer = data.db.main_write_txn()?;
let common_store = data.db.common_store();
common_store
.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
common_store.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)?;
writer.commit()?;
Ok(HttpResponse::Ok().finish())
}
pub async fn set_unhealthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
pub async fn set_unhealthy(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
let mut writer = data.db.main_write_txn()?;
let common_store = data.db.common_store();
common_store
.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
common_store.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())?;
writer.commit()?;
Ok(HttpResponse::Ok().finish())
}
@ -64,7 +46,7 @@ pub struct HealtBody {
pub async fn change_healthyness(
data: web::Data<Data>,
body: web::Json<HealtBody>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
if body.health {
set_healthy(data).await
} else {

View file

@ -1,4 +1,3 @@
use actix_web as aweb;
use actix_web::{delete, get, post, put, web, HttpResponse};
use chrono::{DateTime, Utc};
use log::error;
@ -29,11 +28,8 @@ pub struct IndexResponse {
}
#[get("/indexes")]
pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
pub async fn list_indexes(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
let reader = data.db.main_read_txn()?;
let mut response = Vec::new();
@ -42,26 +38,20 @@ pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
match index {
Some(index) => {
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
"Impossible to get the name of an index",
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
.created_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the create date of an index",
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
.updated_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the last update date of an index",
))?;
let primary_key = match index.main.schema(&reader) {
@ -95,37 +85,28 @@ pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
pub async fn get_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
"Impossible to get the name of an index",
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
.created_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the create date of an index",
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
.updated_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the last update date of an index",
))?;
let primary_key = match index.main.schema(&reader) {
@ -157,11 +138,11 @@ pub struct IndexCreateRequest {
pub async fn create_index(
data: web::Data<Data>,
body: web::Json<IndexCreateRequest>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
if let (None, None) = (body.name.clone(), body.uid.clone()) {
return Err(
ResponseError::BadRequest("Index creation must have an uid".to_string()).into(),
);
return Err(ResponseError::bad_request(
"Index creation must have an uid",
));
}
let uid = match body.uid.clone() {
@ -172,7 +153,7 @@ pub async fn create_index(
{
uid
} else {
return Err(ResponseError::InvalidIndexUid.into());
return Err(ResponseError::InvalidIndexUid);
}
}
None => loop {
@ -186,50 +167,33 @@ pub async fn create_index(
let created_index = data
.db
.create_index(&uid)
.map_err(|e| ResponseError::CreateIndex(e.to_string()))?;
.map_err(ResponseError::create_index)?;
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.main_write_txn()?;
let name = body.name.clone().unwrap_or(uid.clone());
created_index
.main
.put_name(&mut writer, &name)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
created_index.main.put_name(&mut writer, &name)?;
let created_at = created_index
.main
.created_at(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("".to_string()))?;
.created_at(&writer)?
.ok_or(ResponseError::internal("Impossible to read created at"))?;
let updated_at = created_index
.main
.updated_at(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("".to_string()))?;
.updated_at(&writer)?
.ok_or(ResponseError::internal("Impossible to read updated at"))?;
if let Some(id) = body.primary_key.clone() {
if let Some(mut schema) = created_index
.main
.schema(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
{
if let Some(mut schema) = created_index.main.schema(&writer)? {
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
created_index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
.map_err(ResponseError::bad_request)?;
created_index.main.put_schema(&mut writer, &schema)?;
}
}
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Created().json(IndexResponse {
name,
@ -262,83 +226,53 @@ pub async fn update_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<IndexCreateRequest>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.main_write_txn()?;
if let Some(name) = body.name.clone() {
index
.main
.put_name(&mut writer, &name)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
index.main.put_name(&mut writer, &name)?;
}
if let Some(id) = body.primary_key.clone() {
if let Some(mut schema) = index
.main
.schema(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
{
if let Some(mut schema) = index.main.schema(&writer)? {
match schema.primary_key() {
Some(_) => {
return Err(ResponseError::BadRequest(
"The primary key cannot be updated".to_string(),
)
.into());
return Err(ResponseError::bad_request(
"The primary key cannot be updated",
));
}
None => {
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
schema.set_primary_key(&id)?;
index.main.put_schema(&mut writer, &schema)?;
}
}
}
}
index
.main
.put_updated_at(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
index.main.put_updated_at(&mut writer)?;
writer.commit()?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
"Impossible to get the name of an index",
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
.created_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the create date of an index",
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
.updated_at(&reader)?
.ok_or(ResponseError::internal(
"Impossible to get the last update date of an index",
))?;
let primary_key = match index.main.schema(&reader) {
@ -362,12 +296,10 @@ pub async fn update_index(
pub async fn delete_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
data.db
.delete_index(&path.index_uid)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
) -> Result<HttpResponse, ResponseError> {
data.db.delete_index(&path.index_uid)?;
HttpResponse::NoContent().await
Ok(HttpResponse::NoContent().finish())
}
#[derive(Default, Deserialize)]
@ -380,24 +312,22 @@ pub struct UpdateParam {
pub async fn get_update_status(
data: web::Data<Data>,
path: web::Path<UpdateParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.update_read_txn()?;
let status = index
.update_status(&reader, path.update_id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
let status = index.update_status(&reader, path.update_id)?;
match status {
Some(status) => Ok(HttpResponse::Ok().json(status)),
None => Err(ResponseError::NotFound(format!("Update {} not found", path.update_id)).into()),
None => Err(ResponseError::NotFound(format!(
"Update {} not found",
path.update_id
))),
}
}
@ -405,20 +335,15 @@ pub async fn get_update_status(
pub async fn get_all_updates_status(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.update_read_txn()?;
let response = index
.all_updates_status(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let response = index.all_updates_status(&reader)?;
Ok(HttpResponse::Ok().json(response))
}

View file

@ -2,13 +2,11 @@ use std::collections::{HashSet, HashMap};
use std::time::Duration;
use log::warn;
use meilisearch_core::Index;
use actix_web as aweb;
use actix_web::{get, web};
use serde::{Deserialize};
use serde::Deserialize;
use crate::error::ResponseError;
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchResult};
use crate::helpers::meilisearch::{IndexSearchExt, SearchResult};
use crate::routes::IndexParam;
use crate::Data;
@ -32,24 +30,18 @@ pub async fn search_with_url_query(
data: web::Data<Data>,
path: web::Path<IndexParam>,
params: web::Query<SearchQuery>,
) -> aweb::Result<web::Json<SearchResult>> {
) -> Result<web::Json<SearchResult>, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ok_or(ResponseError::Internal(
"Impossible to retrieve the schema".to_string(),
))?;
.schema(&reader)?
.ok_or(ResponseError::internal("Impossible to retrieve the schema"))?;
let mut search_builder = index.new_search(params.q.clone());
@ -145,11 +137,5 @@ pub async fn search_with_url_query(
}
}
let response = match search_builder.search(&reader) {
Ok(response) => response,
Err(Error::Internal(message)) => return Err(ResponseError::Internal(message).into()),
Err(others) => return Err(ResponseError::BadRequest(others.to_string()).into()),
};
Ok(web::Json(response))
Ok(web::Json(search_builder.search(&reader)?))
}

View file

@ -1,4 +1,3 @@
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES};
use std::collections::{BTreeMap, BTreeSet, HashSet};
@ -12,26 +11,19 @@ pub async fn update_all(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Settings>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = body
.into_inner()
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -40,71 +32,42 @@ pub async fn update_all(
pub async fn get_all(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let stop_words_fst = index
.main
.stop_words_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words = stop_words_fst
.unwrap_or_default()
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words_fst = index.main.stop_words_fst(&reader)?;
let stop_words = stop_words_fst.unwrap_or_default().stream().into_strs()?;
let stop_words: BTreeSet<String> = stop_words.into_iter().collect();
let synonyms_fst = index
.main
.synonyms_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let synonyms_list = synonyms_fst
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let synonyms_fst = index.main.synonyms_fst(&reader)?.unwrap_or_default();
let synonyms_list = synonyms_fst.stream().into_strs()?;
let mut synonyms = BTreeMap::new();
let index_synonyms = &index.synonyms;
for synonym in synonyms_list {
let alternative_list = index_synonyms
.synonyms(&reader, synonym.as_bytes())
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
if let Some(list) = alternative_list {
let list = list
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let list = list.stream().into_strs()?;
synonyms.insert(synonym, list);
}
}
let ranking_rules = index
.main
.ranking_rules(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ranking_rules(&reader)?
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
.into_iter()
.map(|r| r.to_string())
.collect();
let distinct_attribute = index
.main
.distinct_attribute(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let distinct_attribute = index.main.distinct_attribute(&reader)?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)?;
let searchable_attributes = schema.clone().map(|s| {
s.indexed_name()
@ -139,15 +102,12 @@ pub async fn get_all(
pub async fn delete_all(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data.db.update_write_txn()?;
let settings = SettingsUpdate {
ranking_rules: UpdateState::Clear,
@ -160,12 +120,8 @@ pub async fn delete_all(
accept_new_fields: UpdateState::Clear,
};
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -174,20 +130,16 @@ pub async fn delete_all(
pub async fn get_rules(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let ranking_rules = index
.main
.ranking_rules(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ranking_rules(&reader)?
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
.into_iter()
.map(|r| r.to_string())
@ -201,30 +153,21 @@ pub async fn update_rules(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Option<Vec<String>>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = Settings {
ranking_rules: Some(body.into_inner()),
..Settings::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -233,28 +176,21 @@ pub async fn update_rules(
pub async fn delete_rules(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data.db.update_write_txn()?;
let settings = SettingsUpdate {
ranking_rules: UpdateState::Clear,
..SettingsUpdate::default()
};
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -263,19 +199,13 @@ pub async fn delete_rules(
pub async fn get_distinct(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let distinct_attribute = index
.main
.distinct_attribute(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let distinct_attribute = index.main.distinct_attribute(&reader)?;
Ok(HttpResponse::Ok().json(distinct_attribute))
}
@ -285,30 +215,21 @@ pub async fn update_distinct(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Option<String>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = Settings {
distinct_attribute: Some(body.into_inner()),
..Settings::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -317,28 +238,21 @@ pub async fn update_distinct(
pub async fn delete_distinct(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let mut writer = data.db.update_write_txn()?;
let settings = SettingsUpdate {
distinct_attribute: UpdateState::Clear,
..SettingsUpdate::default()
};
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -347,19 +261,13 @@ pub async fn delete_distinct(
pub async fn get_searchable(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let schema = index.main.schema(&reader)?;
let searchable_attributes: Option<Vec<String>> =
schema.map(|s| s.indexed_name().iter().map(|i| (*i).to_string()).collect());
@ -371,30 +279,21 @@ pub async fn update_searchable(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Option<Vec<String>>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = Settings {
searchable_attributes: Some(body.into_inner()),
..Settings::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -403,27 +302,20 @@ pub async fn update_searchable(
pub async fn delete_searchable(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
searchable_attributes: UpdateState::Clear,
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -432,20 +324,14 @@ pub async fn delete_searchable(
pub async fn get_displayed(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)?;
let displayed_attributes: Option<HashSet<String>> = schema.map(|s| {
s.displayed_name()
@ -462,30 +348,21 @@ pub async fn update_displayed(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Option<HashSet<String>>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = Settings {
displayed_attributes: Some(body.into_inner()),
..Settings::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -494,27 +371,20 @@ pub async fn update_displayed(
pub async fn delete_displayed(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
displayed_attributes: UpdateState::Clear,
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -523,20 +393,14 @@ pub async fn delete_displayed(
pub async fn get_accept_new_fields(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)?;
let accept_new_fields = schema.map(|s| s.accept_new_fields());
@ -548,30 +412,21 @@ pub async fn update_accept_new_fields(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Option<bool>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = Settings {
accept_new_fields: Some(body.into_inner()),
..Settings::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}

View file

@ -1,6 +1,5 @@
use std::collections::HashMap;
use actix_web as aweb;
use actix_web::{get, web};
use chrono::{DateTime, Utc};
use log::error;
@ -25,36 +24,22 @@ pub struct IndexStatsResponse {
pub async fn index_stats(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<web::Json<IndexStatsResponse>> {
) -> Result<web::Json<IndexStatsResponse>, ResponseError> {
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.open_index(&path.index_uid)
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let number_of_documents = index
.main
.number_of_documents(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let number_of_documents = index.main.number_of_documents(&reader)?;
let fields_frequency = index
.main
.fields_frequency(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let fields_frequency = index.main.fields_frequency(&reader)?.unwrap_or_default();
let update_reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_reader = data.db.update_read_txn()?;
let is_indexing = data
.is_indexing(&update_reader, &path.index_uid)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.is_indexing(&update_reader, &path.index_uid)?
.unwrap_or_default();
Ok(web::Json(IndexStatsResponse {
@ -73,37 +58,23 @@ pub struct StatsResult {
}
#[get("/stats")]
pub async fn get_stats(data: web::Data<Data>) -> aweb::Result<web::Json<StatsResult>> {
pub async fn get_stats(data: web::Data<Data>) -> Result<web::Json<StatsResult>, ResponseError> {
let mut index_list = HashMap::new();
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let update_reader = data.db.update_read_txn()?;
let indexes_set = data.db.indexes_uids();
for index_uid in indexes_set {
let index = data.db.open_index(&index_uid);
match index {
Some(index) => {
let number_of_documents = index
.main
.number_of_documents(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let number_of_documents = index.main.number_of_documents(&reader)?;
let fields_frequency = index
.main
.fields_frequency(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let fields_frequency = index.main.fields_frequency(&reader)?.unwrap_or_default();
let is_indexing = data
.is_indexing(&update_reader, &index_uid)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.is_indexing(&update_reader, &index_uid)?
.unwrap_or_default();
let response = IndexStatsResponse {
@ -120,16 +91,14 @@ pub async fn get_stats(data: web::Data<Data>) -> aweb::Result<web::Json<StatsRes
}
}
let database_size = WalkDir::new(data.db_path.clone())
let database_size = WalkDir::new(&data.db_path)
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| entry.metadata().ok())
.filter(|metadata| metadata.is_file())
.fold(0, |acc, m| acc + m.len());
let last_update = data
.last_update(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let last_update = data.last_update(&reader)?;
Ok(web::Json(StatsResult {
database_size,

View file

@ -1,32 +1,23 @@
use std::collections::BTreeSet;
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use std::collections::BTreeSet;
use crate::error::ResponseError;
use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
#[get("/indexes/{index_uid}/settings/stop-words")]
pub async fn get(data: web::Data<Data>, path: web::Path<IndexParam>) -> aweb::Result<HttpResponse> {
pub async fn get(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words_fst = index
.main
.stop_words_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words = stop_words_fst
.unwrap_or_default()
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data.db.main_read_txn()?;
let stop_words_fst = index.main.stop_words_fst(&reader)?;
let stop_words = stop_words_fst.unwrap_or_default().stream().into_strs()?;
Ok(HttpResponse::Ok().json(stop_words))
}
@ -36,27 +27,20 @@ pub async fn update(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<BTreeSet<String>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
stop_words: UpdateState::Update(body.into_inner()),
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -65,27 +49,20 @@ pub async fn update(
pub async fn delete(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
stop_words: UpdateState::Clear,
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}

View file

@ -1,6 +1,5 @@
use std::collections::BTreeMap;
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use indexmap::IndexMap;
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
@ -10,41 +9,27 @@ use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
#[get("/indexes/{index_uid}/settings/synonyms")]
pub async fn get(data: web::Data<Data>, path: web::Path<IndexParam>) -> aweb::Result<HttpResponse> {
pub async fn get(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()?;
let synonyms_fst = index
.main
.synonyms_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let synonyms_list = synonyms_fst
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let synonyms_fst = index.main.synonyms_fst(&reader)?.unwrap_or_default();
let synonyms_list = synonyms_fst.stream().into_strs()?;
let mut synonyms = IndexMap::new();
let index_synonyms = &index.synonyms;
for synonym in synonyms_list {
let alternative_list = index_synonyms
.synonyms(&reader, synonym.as_bytes())
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
if let Some(list) = alternative_list {
let list = list
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let list = list.stream().into_strs()?;
synonyms.insert(synonym, list);
}
}
@ -57,27 +42,20 @@ pub async fn update(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<BTreeMap<String, Vec<String>>>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
synonyms: UpdateState::Update(body.into_inner()),
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
@ -86,28 +64,21 @@ pub async fn update(
pub async fn delete(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
) -> Result<HttpResponse, ResponseError> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
let settings = SettingsUpdate {
synonyms: UpdateState::Clear,
..SettingsUpdate::default()
};
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data.db.update_write_txn()?;
let update_id = index.settings_update(&mut writer, settings)?;
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}