mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-26 06:44:27 +01:00
simplify error handling by impl errors traits on ResponseError
This commit is contained in:
parent
4bd7e46ba6
commit
e74d2c1872
@ -7,39 +7,109 @@ use serde_json::json;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ResponseError {
|
pub enum ResponseError {
|
||||||
Internal(String),
|
|
||||||
BadRequest(String),
|
|
||||||
MissingAuthorizationHeader,
|
|
||||||
InvalidToken(String),
|
|
||||||
NotFound(String),
|
|
||||||
IndexNotFound(String),
|
|
||||||
DocumentNotFound(String),
|
|
||||||
MissingHeader(String),
|
|
||||||
FilterParsing(String),
|
|
||||||
BadParameter(String, String),
|
BadParameter(String, String),
|
||||||
OpenIndex(String),
|
BadRequest(String),
|
||||||
CreateIndex(String),
|
CreateIndex(String),
|
||||||
|
DocumentNotFound(String),
|
||||||
|
IndexNotFound(String),
|
||||||
|
Internal(String),
|
||||||
InvalidIndexUid,
|
InvalidIndexUid,
|
||||||
|
InvalidToken(String),
|
||||||
Maintenance,
|
Maintenance,
|
||||||
|
MissingAuthorizationHeader,
|
||||||
|
MissingFilterValue,
|
||||||
|
MissingHeader(String),
|
||||||
|
NotFound(String),
|
||||||
|
OpenIndex(String),
|
||||||
|
FilterParsing(String),
|
||||||
|
RetrieveDocument(u64, String),
|
||||||
|
SearchDocuments(String),
|
||||||
|
UnknownFilteredAttribute,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseError {
|
||||||
|
pub fn internal(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::Internal(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bad_request(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::BadRequest(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn missing_authorization_header() -> ResponseError {
|
||||||
|
ResponseError::MissingAuthorizationHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invalid_token(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::InvalidToken(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_found(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::NotFound(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index_not_found(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::IndexNotFound(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn document_not_found(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::DocumentNotFound(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn missing_header(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::MissingHeader(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bad_parameter(param: impl fmt::Display, err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::BadParameter(param.to_string(), err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open_index(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::OpenIndex(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_index(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::CreateIndex(err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn invalid_index_uid() -> ResponseError {
|
||||||
|
ResponseError::InvalidIndexUid
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maintenance() -> ResponseError {
|
||||||
|
ResponseError::Maintenance
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn retrieve_document(doc_id: u64, err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::RetrieveDocument(doc_id, err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn search_documents(err: impl fmt::Display) -> ResponseError {
|
||||||
|
ResponseError::SearchDocuments(err.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ResponseError {
|
impl fmt::Display for ResponseError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Internal(err) => write!(f, "{}", err),
|
|
||||||
Self::BadRequest(err) => write!(f, "{}", err),
|
|
||||||
Self::MissingAuthorizationHeader => write!(f, "You must have an authorization token"),
|
|
||||||
Self::InvalidToken(err) => write!(f, "Invalid API key: {}", err),
|
|
||||||
Self::NotFound(err) => write!(f, "{} not found", err),
|
|
||||||
Self::IndexNotFound(index_uid) => write!(f, "Index {} not found", index_uid),
|
|
||||||
Self::DocumentNotFound(document_id) => write!(f, "Document with id {} not found", document_id),
|
|
||||||
Self::MissingHeader(header) => write!(f, "Header {} is missing", header),
|
|
||||||
Self::BadParameter(param, err) => write!(f, "Url parameter {} error: {}", param, err),
|
Self::BadParameter(param, err) => write!(f, "Url parameter {} error: {}", param, err),
|
||||||
Self::OpenIndex(err) => write!(f, "Impossible to open index; {}", err),
|
Self::BadRequest(err) => write!(f, "{}", err),
|
||||||
Self::CreateIndex(err) => write!(f, "Impossible to create index; {}", err),
|
Self::CreateIndex(err) => write!(f, "Impossible to create index; {}", err),
|
||||||
Self::InvalidIndexUid => write!(f, "Index must have a valid uid; Index uid can be of type integer or string only composed of alphanumeric characters, hyphens (-) and underscores (_)."),
|
Self::DocumentNotFound(document_id) => write!(f, "Document with id {} not found", document_id),
|
||||||
Self::Maintenance => write!(f, "Server is in maintenance, please try again later"),
|
Self::IndexNotFound(index_uid) => write!(f, "Index {} not found", index_uid),
|
||||||
|
Self::Internal(err) => write!(f, "{}", err),
|
||||||
|
Self::InvalidIndexUid => f.write_str("Index must have a valid uid; Index uid can be of type integer or string only composed of alphanumeric characters, hyphens (-) and underscores (_)."),
|
||||||
|
Self::InvalidToken(err) => write!(f, "Invalid API key: {}", err),
|
||||||
|
Self::Maintenance => f.write_str("Server is in maintenance, please try again later"),
|
||||||
Self::FilterParsing(err) => write!(f, "parsing error: {}", err),
|
Self::FilterParsing(err) => write!(f, "parsing error: {}", err),
|
||||||
|
Self::MissingAuthorizationHeader => f.write_str("You must have an authorization token"),
|
||||||
|
Self::MissingFilterValue => f.write_str("a filter doesn't have a value to compare it with"),
|
||||||
|
Self::MissingHeader(header) => write!(f, "Header {} is missing", header),
|
||||||
|
Self::NotFound(err) => write!(f, "{} not found", err),
|
||||||
|
Self::OpenIndex(err) => write!(f, "Impossible to open index; {}", err),
|
||||||
|
Self::RetrieveDocument(id, err) => write!(f, "impossible to retrieve the document with id: {}; {}", id, err),
|
||||||
|
Self::SearchDocuments(err) => write!(f, "impossible to search documents; {}", err),
|
||||||
|
Self::UnknownFilteredAttribute => f.write_str("a filter is specifying an unknown schema attribute"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,20 +123,66 @@ impl aweb::error::ResponseError for ResponseError {
|
|||||||
|
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
|
||||||
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
|
|
||||||
Self::MissingAuthorizationHeader => StatusCode::FORBIDDEN,
|
|
||||||
Self::InvalidToken(_) => StatusCode::UNAUTHORIZED,
|
|
||||||
Self::NotFound(_) => StatusCode::NOT_FOUND,
|
|
||||||
Self::IndexNotFound(_) => StatusCode::NOT_FOUND,
|
|
||||||
Self::DocumentNotFound(_) => StatusCode::NOT_FOUND,
|
|
||||||
Self::MissingHeader(_) => StatusCode::UNAUTHORIZED,
|
|
||||||
Self::BadParameter(_, _) => StatusCode::BAD_REQUEST,
|
Self::BadParameter(_, _) => StatusCode::BAD_REQUEST,
|
||||||
Self::OpenIndex(_) => StatusCode::BAD_REQUEST,
|
Self::BadRequest(_) => StatusCode::BAD_REQUEST,
|
||||||
Self::CreateIndex(_) => StatusCode::BAD_REQUEST,
|
Self::CreateIndex(_) => StatusCode::BAD_REQUEST,
|
||||||
|
Self::DocumentNotFound(_) => StatusCode::NOT_FOUND,
|
||||||
|
Self::IndexNotFound(_) => StatusCode::NOT_FOUND,
|
||||||
|
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Self::InvalidIndexUid => StatusCode::BAD_REQUEST,
|
Self::InvalidIndexUid => StatusCode::BAD_REQUEST,
|
||||||
|
Self::InvalidToken(_) => StatusCode::UNAUTHORIZED,
|
||||||
Self::Maintenance => StatusCode::SERVICE_UNAVAILABLE,
|
Self::Maintenance => StatusCode::SERVICE_UNAVAILABLE,
|
||||||
Self::FilterParsing(_) => StatusCode::BAD_REQUEST,
|
Self::FilterParsing(_) => StatusCode::BAD_REQUEST,
|
||||||
|
Self::MissingAuthorizationHeader => StatusCode::FORBIDDEN,
|
||||||
|
Self::MissingFilterValue => StatusCode::BAD_REQUEST,
|
||||||
|
Self::MissingHeader(_) => StatusCode::UNAUTHORIZED,
|
||||||
|
Self::NotFound(_) => StatusCode::NOT_FOUND,
|
||||||
|
Self::OpenIndex(_) => StatusCode::BAD_REQUEST,
|
||||||
|
Self::RetrieveDocument(_, _) => StatusCode::BAD_REQUEST,
|
||||||
|
Self::SearchDocuments(_) => StatusCode::BAD_REQUEST,
|
||||||
|
Self::UnknownFilteredAttribute => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<meilisearch_core::HeedError> for ResponseError {
|
||||||
|
fn from(err: meilisearch_core::HeedError) -> ResponseError {
|
||||||
|
ResponseError::Internal(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<meilisearch_core::FstError> for ResponseError {
|
||||||
|
fn from(err: meilisearch_core::FstError) -> ResponseError {
|
||||||
|
ResponseError::Internal(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<meilisearch_core::Error> for ResponseError {
|
||||||
|
fn from(err: meilisearch_core::Error) -> ResponseError {
|
||||||
|
use meilisearch_core::pest_error::LineColLocation::*;
|
||||||
|
match err {
|
||||||
|
meilisearch_core::Error::FilterParseError(e) => {
|
||||||
|
let (line, column) = match e.line_col {
|
||||||
|
Span((line, _), (column, _)) => (line, column),
|
||||||
|
Pos((line, column)) => (line, column),
|
||||||
|
};
|
||||||
|
let message = format!("parsing error on line {} at column {}: {}", line, column, e.variant.message());
|
||||||
|
|
||||||
|
ResponseError::FilterParsing(message)
|
||||||
|
},
|
||||||
|
_ => ResponseError::Internal(err.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<meilisearch_schema::Error> for ResponseError {
|
||||||
|
fn from(err: meilisearch_schema::Error) -> ResponseError {
|
||||||
|
ResponseError::Internal(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<actix_http::Error> for ResponseError {
|
||||||
|
fn from(err: actix_http::Error) -> ResponseError {
|
||||||
|
ResponseError::Internal(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::convert::From;
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
@ -19,74 +16,7 @@ use serde_json::Value;
|
|||||||
use siphasher::sip::SipHasher;
|
use siphasher::sip::SipHasher;
|
||||||
use slice_group_by::GroupBy;
|
use slice_group_by::GroupBy;
|
||||||
|
|
||||||
#[derive(Debug)]
|
use crate::error::ResponseError;
|
||||||
pub enum Error {
|
|
||||||
SearchDocuments(String),
|
|
||||||
RetrieveDocument(u64, String),
|
|
||||||
DocumentNotFound(u64),
|
|
||||||
CropFieldWrongType(String),
|
|
||||||
FilterParsing(String),
|
|
||||||
AttributeNotFoundOnDocument(String),
|
|
||||||
AttributeNotFoundOnSchema(String),
|
|
||||||
MissingFilterValue,
|
|
||||||
UnknownFilteredAttribute,
|
|
||||||
Internal(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for Error {}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
SearchDocuments(err) => write!(f, "impossible to search documents; {}", err),
|
|
||||||
RetrieveDocument(id, err) => write!(
|
|
||||||
f,
|
|
||||||
"impossible to retrieve the document with id: {}; {}",
|
|
||||||
id, err
|
|
||||||
),
|
|
||||||
DocumentNotFound(id) => write!(f, "document {} not found", id),
|
|
||||||
CropFieldWrongType(field) => {
|
|
||||||
write!(f, "the field {} cannot be cropped it's not a string", field)
|
|
||||||
}
|
|
||||||
AttributeNotFoundOnDocument(field) => {
|
|
||||||
write!(f, "field {} is not found on document", field)
|
|
||||||
}
|
|
||||||
AttributeNotFoundOnSchema(field) => write!(f, "field {} is not found on schema", field),
|
|
||||||
MissingFilterValue => f.write_str("a filter doesn't have a value to compare it with"),
|
|
||||||
UnknownFilteredAttribute => {
|
|
||||||
f.write_str("a filter is specifying an unknown schema attribute")
|
|
||||||
}
|
|
||||||
Internal(err) => write!(f, "internal error; {}", err),
|
|
||||||
FilterParsing(err) => write!(f, "filter parsing error: {}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<meilisearch_core::Error> for Error {
|
|
||||||
fn from(error: meilisearch_core::Error) -> Self {
|
|
||||||
use meilisearch_core::pest_error::LineColLocation::*;
|
|
||||||
match error {
|
|
||||||
meilisearch_core::Error::FilterParseError(e) => {
|
|
||||||
let (line, column) = match e.line_col {
|
|
||||||
Span((line, _), (column, _)) => (line, column),
|
|
||||||
Pos((line, column)) => (line, column),
|
|
||||||
};
|
|
||||||
let message = format!("parsing error on line {} at column {}: {}", line, column, e.variant.message());
|
|
||||||
|
|
||||||
Error::FilterParsing(message)
|
|
||||||
},
|
|
||||||
_ => Error::Internal(error.to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<heed::Error> for Error {
|
|
||||||
fn from(error: heed::Error) -> Self {
|
|
||||||
Error::Internal(error.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait IndexSearchExt {
|
pub trait IndexSearchExt {
|
||||||
fn new_search(&self, query: String) -> SearchBuilder;
|
fn new_search(&self, query: String) -> SearchBuilder;
|
||||||
@ -169,17 +99,14 @@ impl<'a> SearchBuilder<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search(&self, reader: &heed::RoTxn<MainT>) -> Result<SearchResult, Error> {
|
pub fn search(&self, reader: &heed::RoTxn<MainT>) -> Result<SearchResult, ResponseError> {
|
||||||
let schema = self.index.main.schema(reader);
|
let schema = self
|
||||||
let schema = schema.map_err(|e| Error::Internal(e.to_string()))?;
|
.index
|
||||||
let schema = match schema {
|
.main
|
||||||
Some(schema) => schema,
|
.schema(reader)?
|
||||||
None => return Err(Error::Internal(String::from("missing schema"))),
|
.ok_or(ResponseError::internal("missing schema"))?;
|
||||||
};
|
|
||||||
|
|
||||||
let ranked_map = self.index.main.ranked_map(reader);
|
let ranked_map = self.index.main.ranked_map(reader)?.unwrap_or_default();
|
||||||
let ranked_map = ranked_map.map_err(|e| Error::Internal(e.to_string()))?;
|
|
||||||
let ranked_map = ranked_map.unwrap_or_default();
|
|
||||||
|
|
||||||
// Change criteria
|
// Change criteria
|
||||||
let mut query_builder = match self.get_criteria(reader, &ranked_map, &schema)? {
|
let mut query_builder = match self.get_criteria(reader, &ranked_map, &schema)? {
|
||||||
@ -221,9 +148,8 @@ impl<'a> SearchBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result =
|
let result = query_builder.query(reader, &self.query, self.offset..(self.offset + self.limit));
|
||||||
query_builder.query(reader, &self.query, self.offset..(self.offset + self.limit));
|
let (docs, nb_hits) = result.map_err(ResponseError::search_documents)?;
|
||||||
let (docs, nb_hits) = result.map_err(|e| Error::SearchDocuments(e.to_string()))?;
|
|
||||||
let time_ms = start.elapsed().as_millis() as usize;
|
let time_ms = start.elapsed().as_millis() as usize;
|
||||||
|
|
||||||
let mut all_attributes: HashSet<&str> = HashSet::new();
|
let mut all_attributes: HashSet<&str> = HashSet::new();
|
||||||
@ -255,11 +181,19 @@ impl<'a> SearchBuilder<'a> {
|
|||||||
|
|
||||||
let mut hits = Vec::with_capacity(self.limit);
|
let mut hits = Vec::with_capacity(self.limit);
|
||||||
for doc in docs {
|
for doc in docs {
|
||||||
|
// retrieve the content of document in kv store
|
||||||
|
let attributes: Option<HashSet<&str>> = self
|
||||||
|
.attributes_to_retrieve
|
||||||
|
.as_ref()
|
||||||
|
.map(|a| a.iter().map(|a| a.as_str()).collect());
|
||||||
|
|
||||||
let mut document: IndexMap<String, Value> = self
|
let mut document: IndexMap<String, Value> = self
|
||||||
.index
|
.index
|
||||||
.document(reader, Some(&all_attributes), doc.id)
|
.document(reader, attributes.as_ref(), doc.id)
|
||||||
.map_err(|e| Error::RetrieveDocument(doc.id.0, e.to_string()))?
|
.map_err(|e| ResponseError::retrieve_document(doc.id.0, e))?
|
||||||
.ok_or(Error::DocumentNotFound(doc.id.0))?;
|
.ok_or(ResponseError::internal(
|
||||||
|
"Impossible to retrieve a document id returned by the engine",
|
||||||
|
))?;
|
||||||
|
|
||||||
let mut formatted = document.iter()
|
let mut formatted = document.iter()
|
||||||
.filter(|(key, _)| all_formatted.contains(key.as_str()))
|
.filter(|(key, _)| all_formatted.contains(key.as_str()))
|
||||||
@ -320,7 +254,7 @@ impl<'a> SearchBuilder<'a> {
|
|||||||
reader: &heed::RoTxn<MainT>,
|
reader: &heed::RoTxn<MainT>,
|
||||||
ranked_map: &'a RankedMap,
|
ranked_map: &'a RankedMap,
|
||||||
schema: &Schema,
|
schema: &Schema,
|
||||||
) -> Result<Option<Criteria<'a>>, Error> {
|
) -> Result<Option<Criteria<'a>>, ResponseError> {
|
||||||
let ranking_rules = self.index.main.ranking_rules(reader)?;
|
let ranking_rules = self.index.main.ranking_rules(reader)?;
|
||||||
|
|
||||||
if let Some(ranking_rules) = ranking_rules {
|
if let Some(ranking_rules) = ranking_rules {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::{BTreeSet, HashSet};
|
||||||
use std::collections::BTreeSet;
|
|
||||||
|
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{delete, get, post, put, web, HttpResponse};
|
use actix_web::{delete, get, post, put, web, HttpResponse};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -23,22 +21,18 @@ pub struct DocumentParam {
|
|||||||
pub async fn get_document(
|
pub async fn get_document(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<DocumentParam>,
|
path: web::Path<DocumentParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.open_index(&path.index_uid)
|
||||||
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
|
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
|
||||||
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
|
let document_id = meilisearch_core::serde::compute_document_id(&path.document_id);
|
||||||
|
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let response = index
|
let response = index
|
||||||
.document::<Document>(&reader, None, document_id)
|
.document::<Document>(&reader, None, document_id)?
|
||||||
.map_err(|_| ResponseError::DocumentNotFound(path.document_id.clone()))?
|
.ok_or(ResponseError::document_not_found(&path.document_id))?;
|
||||||
.ok_or(ResponseError::DocumentNotFound(path.document_id.clone()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(response))
|
Ok(HttpResponse::Ok().json(response))
|
||||||
}
|
}
|
||||||
@ -47,28 +41,21 @@ pub async fn get_document(
|
|||||||
pub async fn delete_document(
|
pub async fn delete_document(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<DocumentParam>,
|
path: web::Path<DocumentParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.open_index(&path.index_uid)
|
||||||
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
|
.ok_or(ResponseError::index_not_found(&path.index_uid))?;
|
||||||
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
|
let document_id = meilisearch_core::serde::compute_document_id(&path.document_id);
|
||||||
|
|
||||||
let mut update_writer = data
|
let mut update_writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let mut documents_deletion = index.documents_deletion();
|
let mut documents_deletion = index.documents_deletion();
|
||||||
documents_deletion.delete_document_by_id(document_id);
|
documents_deletion.delete_document_by_id(document_id);
|
||||||
|
|
||||||
let update_id = documents_deletion
|
let update_id = documents_deletion.finalize(&mut update_writer)?;
|
||||||
.finalize(&mut update_writer)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
update_writer
|
update_writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -86,32 +73,29 @@ pub async fn get_all_documents(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
params: web::Query<BrowseQuery>,
|
params: web::Query<BrowseQuery>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 offset = params.offset.unwrap_or(0);
|
||||||
let limit = params.limit.unwrap_or(20);
|
let limit = params.limit.unwrap_or(20);
|
||||||
|
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let documents_ids: Result<BTreeSet<_>, _> = index
|
let documents_ids: Result<BTreeSet<_>, _> = index
|
||||||
.documents_fields_counts
|
.documents_fields_counts
|
||||||
.documents_ids(&reader)
|
.documents_ids(&reader)?
|
||||||
.map_err(|_| ResponseError::Internal(path.index_uid.clone()))?
|
|
||||||
.skip(offset)
|
.skip(offset)
|
||||||
.take(limit)
|
.take(limit)
|
||||||
.collect();
|
.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
|
let attributes: Option<HashSet<&str>> = params
|
||||||
.attributes_to_retrieve.as_ref()
|
.attributes_to_retrieve
|
||||||
|
.as_ref()
|
||||||
.map(|a| a.split(',').collect());
|
.map(|a| a.split(',').collect());
|
||||||
|
|
||||||
let mut response = Vec::<Document>::new();
|
let mut response = Vec::<Document>::new();
|
||||||
@ -145,48 +129,33 @@ async fn update_multiple_documents(
|
|||||||
params: web::Query<UpdateDocumentsQuery>,
|
params: web::Query<UpdateDocumentsQuery>,
|
||||||
body: web::Json<Vec<Document>>,
|
body: web::Json<Vec<Document>>,
|
||||||
is_partial: bool,
|
is_partial: bool,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let mut schema = index
|
let mut schema = index
|
||||||
.main
|
.main
|
||||||
.schema(&reader)
|
.schema(&reader)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
.ok_or(ResponseError::internal("Impossible to retrieve the schema"))?;
|
||||||
.ok_or(ResponseError::Internal(
|
|
||||||
"Impossible to retrieve the schema".to_string(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
if schema.primary_key().is_none() {
|
if schema.primary_key().is_none() {
|
||||||
let id = match params.primary_key.clone() {
|
let id = match ¶ms.primary_key {
|
||||||
Some(id) => id,
|
Some(id) => id.to_string(),
|
||||||
None => body.first().and_then(|docs| find_primary_key(docs)).ok_or(
|
None => body
|
||||||
ResponseError::BadRequest("Could not infer a primary key".to_string()),
|
.first()
|
||||||
)?,
|
.and_then(find_primary_key)
|
||||||
|
.ok_or(ResponseError::bad_request("Could not infer a primary key"))?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.main_write_txn()?;
|
||||||
.db
|
|
||||||
.main_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
schema
|
schema.set_primary_key(&id)?;
|
||||||
.set_primary_key(&id)
|
index.main.put_schema(&mut writer, &schema)?;
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut document_addition = if is_partial {
|
let mut document_addition = if is_partial {
|
||||||
@ -199,16 +168,9 @@ async fn update_multiple_documents(
|
|||||||
document_addition.update_document(document);
|
document_addition.update_document(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut update_writer = data
|
let mut update_writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = document_addition.finalize(&mut update_writer)?;
|
||||||
.update_write_txn()
|
update_writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -219,7 +181,7 @@ pub async fn add_documents(
|
|||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
params: web::Query<UpdateDocumentsQuery>,
|
params: web::Query<UpdateDocumentsQuery>,
|
||||||
body: web::Json<Vec<Document>>,
|
body: web::Json<Vec<Document>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
update_multiple_documents(data, path, params, body, false).await
|
update_multiple_documents(data, path, params, body, false).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +191,7 @@ pub async fn update_documents(
|
|||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
params: web::Query<UpdateDocumentsQuery>,
|
params: web::Query<UpdateDocumentsQuery>,
|
||||||
body: web::Json<Vec<Document>>,
|
body: web::Json<Vec<Document>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
update_multiple_documents(data, path, params, body, true).await
|
update_multiple_documents(data, path, params, body, true).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,16 +200,13 @@ pub async fn delete_documents(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Vec<Value>>,
|
body: web::Json<Vec<Value>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let mut documents_deletion = index.documents_deletion();
|
let mut documents_deletion = index.documents_deletion();
|
||||||
|
|
||||||
@ -258,13 +217,9 @@ pub async fn delete_documents(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let update_id = documents_deletion
|
let update_id = documents_deletion.finalize(&mut writer)?;
|
||||||
.finalize(&mut writer)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
|
|
||||||
writer
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -273,24 +228,17 @@ pub async fn delete_documents(
|
|||||||
pub async fn clear_all_documents(
|
pub async fn clear_all_documents(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let update_id = index
|
let update_id = index.clear_all(&mut writer)?;
|
||||||
.clear_all(&mut writer)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
|
|
||||||
writer
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::error::ResponseError;
|
use crate::error::ResponseError;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{get, put, web, HttpResponse};
|
use actix_web::{get, put, web, HttpResponse};
|
||||||
use heed::types::{Str, Unit};
|
use heed::types::{Str, Unit};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -8,49 +7,32 @@ use serde::Deserialize;
|
|||||||
const UNHEALTHY_KEY: &str = "_is_unhealthy";
|
const UNHEALTHY_KEY: &str = "_is_unhealthy";
|
||||||
|
|
||||||
#[get("/health")]
|
#[get("/health")]
|
||||||
pub async fn get_health(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
|
pub async fn get_health(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let common_store = data.db.common_store();
|
let common_store = data.db.common_store();
|
||||||
|
|
||||||
if let Ok(Some(_)) = common_store.get::<_, Str, Unit>(&reader, UNHEALTHY_KEY) {
|
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())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_healthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
|
pub async fn set_healthy(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
|
||||||
let mut writer = data
|
let mut writer = data.db.main_write_txn()?;
|
||||||
.db
|
|
||||||
.main_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
let common_store = data.db.common_store();
|
let common_store = data.db.common_store();
|
||||||
common_store
|
common_store.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)?;
|
||||||
.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)
|
writer.commit()?;
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
writer
|
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_unhealthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
|
pub async fn set_unhealthy(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
|
||||||
let mut writer = data
|
let mut writer = data.db.main_write_txn()?;
|
||||||
.db
|
|
||||||
.main_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
let common_store = data.db.common_store();
|
let common_store = data.db.common_store();
|
||||||
common_store
|
common_store.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())?;
|
||||||
.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())
|
writer.commit()?;
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
writer
|
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
@ -64,7 +46,7 @@ pub struct HealtBody {
|
|||||||
pub async fn change_healthyness(
|
pub async fn change_healthyness(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
body: web::Json<HealtBody>,
|
body: web::Json<HealtBody>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
if body.health {
|
if body.health {
|
||||||
set_healthy(data).await
|
set_healthy(data).await
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{delete, get, post, put, web, HttpResponse};
|
use actix_web::{delete, get, post, put, web, HttpResponse};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use log::error;
|
use log::error;
|
||||||
@ -29,11 +28,8 @@ pub struct IndexResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/indexes")]
|
#[get("/indexes")]
|
||||||
pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
|
pub async fn list_indexes(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let mut response = Vec::new();
|
let mut response = Vec::new();
|
||||||
|
|
||||||
@ -42,26 +38,20 @@ pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
|
|||||||
|
|
||||||
match index {
|
match index {
|
||||||
Some(index) => {
|
Some(index) => {
|
||||||
let name = index
|
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
|
||||||
.main
|
"Impossible to get the name of an index",
|
||||||
.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 created_at = index
|
let created_at = index
|
||||||
.main
|
.main
|
||||||
.created_at(&reader)
|
.created_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the create date of an index",
|
||||||
"Impossible to get the create date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
let updated_at = index
|
let updated_at = index
|
||||||
.main
|
.main
|
||||||
.updated_at(&reader)
|
.updated_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the last update date of an index",
|
||||||
"Impossible to get the last update date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let primary_key = match index.main.schema(&reader) {
|
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(
|
pub async fn get_index(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let name = index
|
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
|
||||||
.main
|
"Impossible to get the name of an index",
|
||||||
.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 created_at = index
|
let created_at = index
|
||||||
.main
|
.main
|
||||||
.created_at(&reader)
|
.created_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the create date of an index",
|
||||||
"Impossible to get the create date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
let updated_at = index
|
let updated_at = index
|
||||||
.main
|
.main
|
||||||
.updated_at(&reader)
|
.updated_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the last update date of an index",
|
||||||
"Impossible to get the last update date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let primary_key = match index.main.schema(&reader) {
|
let primary_key = match index.main.schema(&reader) {
|
||||||
@ -157,11 +138,11 @@ pub struct IndexCreateRequest {
|
|||||||
pub async fn create_index(
|
pub async fn create_index(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
body: web::Json<IndexCreateRequest>,
|
body: web::Json<IndexCreateRequest>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
if let (None, None) = (body.name.clone(), body.uid.clone()) {
|
if let (None, None) = (body.name.clone(), body.uid.clone()) {
|
||||||
return Err(
|
return Err(ResponseError::bad_request(
|
||||||
ResponseError::BadRequest("Index creation must have an uid".to_string()).into(),
|
"Index creation must have an uid",
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let uid = match body.uid.clone() {
|
let uid = match body.uid.clone() {
|
||||||
@ -172,7 +153,7 @@ pub async fn create_index(
|
|||||||
{
|
{
|
||||||
uid
|
uid
|
||||||
} else {
|
} else {
|
||||||
return Err(ResponseError::InvalidIndexUid.into());
|
return Err(ResponseError::InvalidIndexUid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => loop {
|
None => loop {
|
||||||
@ -186,50 +167,33 @@ pub async fn create_index(
|
|||||||
let created_index = data
|
let created_index = data
|
||||||
.db
|
.db
|
||||||
.create_index(&uid)
|
.create_index(&uid)
|
||||||
.map_err(|e| ResponseError::CreateIndex(e.to_string()))?;
|
.map_err(ResponseError::create_index)?;
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.main_write_txn()?;
|
||||||
.db
|
|
||||||
.main_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let name = body.name.clone().unwrap_or(uid.clone());
|
let name = body.name.clone().unwrap_or(uid.clone());
|
||||||
created_index
|
created_index.main.put_name(&mut writer, &name)?;
|
||||||
.main
|
|
||||||
.put_name(&mut writer, &name)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
|
|
||||||
let created_at = created_index
|
let created_at = created_index
|
||||||
.main
|
.main
|
||||||
.created_at(&writer)
|
.created_at(&writer)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal("Impossible to read created at"))?;
|
||||||
.ok_or(ResponseError::Internal("".to_string()))?;
|
|
||||||
|
|
||||||
let updated_at = created_index
|
let updated_at = created_index
|
||||||
.main
|
.main
|
||||||
.updated_at(&writer)
|
.updated_at(&writer)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal("Impossible to read updated at"))?;
|
||||||
.ok_or(ResponseError::Internal("".to_string()))?;
|
|
||||||
|
|
||||||
if let Some(id) = body.primary_key.clone() {
|
if let Some(id) = body.primary_key.clone() {
|
||||||
if let Some(mut schema) = created_index
|
if let Some(mut schema) = created_index.main.schema(&writer)? {
|
||||||
.main
|
|
||||||
.schema(&writer)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
|
||||||
{
|
|
||||||
schema
|
schema
|
||||||
.set_primary_key(&id)
|
.set_primary_key(&id)
|
||||||
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
|
.map_err(ResponseError::bad_request)?;
|
||||||
created_index
|
created_index.main.put_schema(&mut writer, &schema)?;
|
||||||
.main
|
|
||||||
.put_schema(&mut writer, &schema)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Created().json(IndexResponse {
|
Ok(HttpResponse::Created().json(IndexResponse {
|
||||||
name,
|
name,
|
||||||
@ -262,83 +226,53 @@ pub async fn update_index(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<IndexCreateRequest>,
|
body: web::Json<IndexCreateRequest>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let mut writer = data.db.main_write_txn()?;
|
||||||
.db
|
|
||||||
.main_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
if let Some(name) = body.name.clone() {
|
if let Some(name) = body.name.clone() {
|
||||||
index
|
index.main.put_name(&mut writer, &name)?;
|
||||||
.main
|
|
||||||
.put_name(&mut writer, &name)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = body.primary_key.clone() {
|
if let Some(id) = body.primary_key.clone() {
|
||||||
if let Some(mut schema) = index
|
if let Some(mut schema) = index.main.schema(&writer)? {
|
||||||
.main
|
|
||||||
.schema(&writer)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
|
||||||
{
|
|
||||||
match schema.primary_key() {
|
match schema.primary_key() {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
return Err(ResponseError::BadRequest(
|
return Err(ResponseError::bad_request(
|
||||||
"The primary key cannot be updated".to_string(),
|
"The primary key cannot be updated",
|
||||||
)
|
));
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
schema
|
schema.set_primary_key(&id)?;
|
||||||
.set_primary_key(&id)
|
index.main.put_schema(&mut writer, &schema)?;
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
index
|
|
||||||
.main
|
|
||||||
.put_schema(&mut writer, &schema)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
index
|
index.main.put_updated_at(&mut writer)?;
|
||||||
.main
|
writer.commit()?;
|
||||||
.put_updated_at(&mut writer)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
writer
|
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let name = index
|
let name = index.main.name(&reader)?.ok_or(ResponseError::internal(
|
||||||
.main
|
"Impossible to get the name of an index",
|
||||||
.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 created_at = index
|
let created_at = index
|
||||||
.main
|
.main
|
||||||
.created_at(&reader)
|
.created_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the create date of an index",
|
||||||
"Impossible to get the create date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
let updated_at = index
|
let updated_at = index
|
||||||
.main
|
.main
|
||||||
.updated_at(&reader)
|
.updated_at(&reader)?
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?
|
.ok_or(ResponseError::internal(
|
||||||
.ok_or(ResponseError::Internal(
|
"Impossible to get the last update date of an index",
|
||||||
"Impossible to get the last update date of an index".to_string(),
|
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let primary_key = match index.main.schema(&reader) {
|
let primary_key = match index.main.schema(&reader) {
|
||||||
@ -362,12 +296,10 @@ pub async fn update_index(
|
|||||||
pub async fn delete_index(
|
pub async fn delete_index(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
data.db
|
data.db.delete_index(&path.index_uid)?;
|
||||||
.delete_index(&path.index_uid)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
|
|
||||||
HttpResponse::NoContent().await
|
Ok(HttpResponse::NoContent().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Deserialize)]
|
#[derive(Default, Deserialize)]
|
||||||
@ -380,24 +312,22 @@ pub struct UpdateParam {
|
|||||||
pub async fn get_update_status(
|
pub async fn get_update_status(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<UpdateParam>,
|
path: web::Path<UpdateParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.update_read_txn()?;
|
||||||
.db
|
|
||||||
.update_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let status = index
|
let status = index.update_status(&reader, path.update_id)?;
|
||||||
.update_status(&reader, path.update_id)
|
|
||||||
.map_err(|e| ResponseError::Internal(e.to_string()))?;
|
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
Some(status) => Ok(HttpResponse::Ok().json(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(
|
pub async fn get_all_updates_status(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.update_read_txn()?;
|
||||||
.db
|
|
||||||
.update_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let response = index
|
let response = index.all_updates_status(&reader)?;
|
||||||
.all_updates_status(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(response))
|
Ok(HttpResponse::Ok().json(response))
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,11 @@ use std::collections::{HashSet, HashMap};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use meilisearch_core::Index;
|
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{get, web};
|
use actix_web::{get, web};
|
||||||
use serde::{Deserialize};
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::error::ResponseError;
|
use crate::error::ResponseError;
|
||||||
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchResult};
|
use crate::helpers::meilisearch::{IndexSearchExt, SearchResult};
|
||||||
use crate::routes::IndexParam;
|
use crate::routes::IndexParam;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
@ -32,24 +30,18 @@ pub async fn search_with_url_query(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
params: web::Query<SearchQuery>,
|
params: web::Query<SearchQuery>,
|
||||||
) -> aweb::Result<web::Json<SearchResult>> {
|
) -> Result<web::Json<SearchResult>, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let schema = index
|
let schema = index
|
||||||
.main
|
.main
|
||||||
.schema(&reader)
|
.schema(&reader)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
.ok_or(ResponseError::internal("Impossible to retrieve the schema"))?;
|
||||||
.ok_or(ResponseError::Internal(
|
|
||||||
"Impossible to retrieve the schema".to_string(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let mut search_builder = index.new_search(params.q.clone());
|
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(web::Json(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))
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{delete, get, post, web, HttpResponse};
|
use actix_web::{delete, get, post, web, HttpResponse};
|
||||||
use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES};
|
use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES};
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
||||||
@ -12,26 +11,19 @@ pub async fn update_all(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Settings>,
|
body: web::Json<Settings>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
let settings = body
|
let settings = body
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.into_update()
|
.into_update()
|
||||||
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
|
.map_err(ResponseError::bad_request)?;
|
||||||
let update_id = index
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.settings_update(&mut writer, settings)
|
writer.commit()?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
writer
|
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -40,71 +32,42 @@ pub async fn update_all(
|
|||||||
pub async fn get_all(
|
pub async fn get_all(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let stop_words_fst = index
|
let stop_words_fst = index.main.stop_words_fst(&reader)?;
|
||||||
.main
|
let stop_words = stop_words_fst.unwrap_or_default().stream().into_strs()?;
|
||||||
.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: BTreeSet<String> = stop_words.into_iter().collect();
|
let stop_words: BTreeSet<String> = stop_words.into_iter().collect();
|
||||||
|
|
||||||
let synonyms_fst = index
|
let synonyms_fst = index.main.synonyms_fst(&reader)?.unwrap_or_default();
|
||||||
.main
|
let synonyms_list = synonyms_fst.stream().into_strs()?;
|
||||||
.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 mut synonyms = BTreeMap::new();
|
let mut synonyms = BTreeMap::new();
|
||||||
let index_synonyms = &index.synonyms;
|
let index_synonyms = &index.synonyms;
|
||||||
for synonym in synonyms_list {
|
for synonym in synonyms_list {
|
||||||
let alternative_list = index_synonyms
|
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
|
||||||
.synonyms(&reader, synonym.as_bytes())
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
if let Some(list) = alternative_list {
|
if let Some(list) = alternative_list {
|
||||||
let list = list
|
let list = list.stream().into_strs()?;
|
||||||
.stream()
|
|
||||||
.into_strs()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
synonyms.insert(synonym, list);
|
synonyms.insert(synonym, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ranking_rules = index
|
let ranking_rules = index
|
||||||
.main
|
.main
|
||||||
.ranking_rules(&reader)
|
.ranking_rules(&reader)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| r.to_string())
|
.map(|r| r.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let distinct_attribute = index
|
let distinct_attribute = index.main.distinct_attribute(&reader)?;
|
||||||
.main
|
|
||||||
.distinct_attribute(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let schema = index
|
let schema = index.main.schema(&reader)?;
|
||||||
.main
|
|
||||||
.schema(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let searchable_attributes = schema.clone().map(|s| {
|
let searchable_attributes = schema.clone().map(|s| {
|
||||||
s.indexed_name()
|
s.indexed_name()
|
||||||
@ -139,15 +102,12 @@ pub async fn get_all(
|
|||||||
pub async fn delete_all(
|
pub async fn delete_all(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let settings = SettingsUpdate {
|
let settings = SettingsUpdate {
|
||||||
ranking_rules: UpdateState::Clear,
|
ranking_rules: UpdateState::Clear,
|
||||||
@ -160,12 +120,8 @@ pub async fn delete_all(
|
|||||||
accept_new_fields: UpdateState::Clear,
|
accept_new_fields: UpdateState::Clear,
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = index
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.settings_update(&mut writer, settings)
|
writer.commit()?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
writer
|
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -174,20 +130,16 @@ pub async fn delete_all(
|
|||||||
pub async fn get_rules(
|
pub async fn get_rules(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let ranking_rules = index
|
let ranking_rules = index
|
||||||
.main
|
.main
|
||||||
.ranking_rules(&reader)
|
.ranking_rules(&reader)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| r.to_string())
|
.map(|r| r.to_string())
|
||||||
@ -201,30 +153,21 @@ pub async fn update_rules(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Option<Vec<String>>>,
|
body: web::Json<Option<Vec<String>>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = Settings {
|
||||||
ranking_rules: Some(body.into_inner()),
|
ranking_rules: Some(body.into_inner()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
|
||||||
.update_write_txn()
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -233,28 +176,21 @@ pub async fn update_rules(
|
|||||||
pub async fn delete_rules(
|
pub async fn delete_rules(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let settings = SettingsUpdate {
|
let settings = SettingsUpdate {
|
||||||
ranking_rules: UpdateState::Clear,
|
ranking_rules: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = index
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.settings_update(&mut writer, settings)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
writer
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -263,19 +199,13 @@ pub async fn delete_rules(
|
|||||||
pub async fn get_distinct(
|
pub async fn get_distinct(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
let distinct_attribute = index.main.distinct_attribute(&reader)?;
|
||||||
.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(HttpResponse::Ok().json(distinct_attribute))
|
Ok(HttpResponse::Ok().json(distinct_attribute))
|
||||||
}
|
}
|
||||||
@ -285,30 +215,21 @@ pub async fn update_distinct(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Option<String>>,
|
body: web::Json<Option<String>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = Settings {
|
||||||
distinct_attribute: Some(body.into_inner()),
|
distinct_attribute: Some(body.into_inner()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
|
||||||
.update_write_txn()
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -317,28 +238,21 @@ pub async fn update_distinct(
|
|||||||
pub async fn delete_distinct(
|
pub async fn delete_distinct(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
|
||||||
.update_write_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let settings = SettingsUpdate {
|
let settings = SettingsUpdate {
|
||||||
distinct_attribute: UpdateState::Clear,
|
distinct_attribute: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = index
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.settings_update(&mut writer, settings)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
writer
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -347,19 +261,13 @@ pub async fn delete_distinct(
|
|||||||
pub async fn get_searchable(
|
pub async fn get_searchable(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
let schema = index.main.schema(&reader)?;
|
||||||
.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()))?;
|
|
||||||
let searchable_attributes: Option<Vec<String>> =
|
let searchable_attributes: Option<Vec<String>> =
|
||||||
schema.map(|s| s.indexed_name().iter().map(|i| (*i).to_string()).collect());
|
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>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Option<Vec<String>>>,
|
body: web::Json<Option<Vec<String>>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = Settings {
|
||||||
searchable_attributes: Some(body.into_inner()),
|
searchable_attributes: Some(body.into_inner()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
|
||||||
.update_write_txn()
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -403,27 +302,20 @@ pub async fn update_searchable(
|
|||||||
pub async fn delete_searchable(
|
pub async fn delete_searchable(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
searchable_attributes: UpdateState::Clear,
|
searchable_attributes: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.update_write_txn()
|
writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -432,20 +324,14 @@ pub async fn delete_searchable(
|
|||||||
pub async fn get_displayed(
|
pub async fn get_displayed(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let schema = index
|
let schema = index.main.schema(&reader)?;
|
||||||
.main
|
|
||||||
.schema(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let displayed_attributes: Option<HashSet<String>> = schema.map(|s| {
|
let displayed_attributes: Option<HashSet<String>> = schema.map(|s| {
|
||||||
s.displayed_name()
|
s.displayed_name()
|
||||||
@ -462,30 +348,21 @@ pub async fn update_displayed(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Option<HashSet<String>>>,
|
body: web::Json<Option<HashSet<String>>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = Settings {
|
||||||
displayed_attributes: Some(body.into_inner()),
|
displayed_attributes: Some(body.into_inner()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
|
||||||
.update_write_txn()
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -494,27 +371,20 @@ pub async fn update_displayed(
|
|||||||
pub async fn delete_displayed(
|
pub async fn delete_displayed(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
displayed_attributes: UpdateState::Clear,
|
displayed_attributes: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.update_write_txn()
|
writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
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(
|
pub async fn get_accept_new_fields(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let schema = index
|
let schema = index.main.schema(&reader)?;
|
||||||
.main
|
|
||||||
.schema(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let accept_new_fields = schema.map(|s| s.accept_new_fields());
|
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>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Option<bool>>,
|
body: web::Json<Option<bool>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = Settings {
|
||||||
accept_new_fields: Some(body.into_inner()),
|
accept_new_fields: Some(body.into_inner()),
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let settings = settings.into_update().map_err(ResponseError::bad_request)?;
|
||||||
.update_write_txn()
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
writer.commit()?;
|
||||||
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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{get, web};
|
use actix_web::{get, web};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use log::error;
|
use log::error;
|
||||||
@ -25,36 +24,22 @@ pub struct IndexStatsResponse {
|
|||||||
pub async fn index_stats(
|
pub async fn index_stats(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<web::Json<IndexStatsResponse>> {
|
) -> Result<web::Json<IndexStatsResponse>, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(path.index_uid.clone())
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let number_of_documents = index
|
let number_of_documents = index.main.number_of_documents(&reader)?;
|
||||||
.main
|
|
||||||
.number_of_documents(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let fields_frequency = index
|
let fields_frequency = index.main.fields_frequency(&reader)?.unwrap_or_default();
|
||||||
.main
|
|
||||||
.fields_frequency(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let update_reader = data
|
let update_reader = data.db.update_read_txn()?;
|
||||||
.db
|
|
||||||
.update_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let is_indexing = data
|
let is_indexing = data
|
||||||
.is_indexing(&update_reader, &path.index_uid)
|
.is_indexing(&update_reader, &path.index_uid)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
Ok(web::Json(IndexStatsResponse {
|
Ok(web::Json(IndexStatsResponse {
|
||||||
@ -73,37 +58,23 @@ pub struct StatsResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("/stats")]
|
#[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 mut index_list = HashMap::new();
|
||||||
|
|
||||||
let reader = data
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
let update_reader = data.db.update_read_txn()?;
|
||||||
.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 indexes_set = data.db.indexes_uids();
|
let indexes_set = data.db.indexes_uids();
|
||||||
for index_uid in indexes_set {
|
for index_uid in indexes_set {
|
||||||
let index = data.db.open_index(&index_uid);
|
let index = data.db.open_index(&index_uid);
|
||||||
match index {
|
match index {
|
||||||
Some(index) => {
|
Some(index) => {
|
||||||
let number_of_documents = index
|
let number_of_documents = index.main.number_of_documents(&reader)?;
|
||||||
.main
|
|
||||||
.number_of_documents(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let fields_frequency = index
|
let fields_frequency = index.main.fields_frequency(&reader)?.unwrap_or_default();
|
||||||
.main
|
|
||||||
.fields_frequency(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let is_indexing = data
|
let is_indexing = data
|
||||||
.is_indexing(&update_reader, &index_uid)
|
.is_indexing(&update_reader, &index_uid)?
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let response = IndexStatsResponse {
|
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()
|
.into_iter()
|
||||||
.filter_map(|entry| entry.ok())
|
.filter_map(|entry| entry.ok())
|
||||||
.filter_map(|entry| entry.metadata().ok())
|
.filter_map(|entry| entry.metadata().ok())
|
||||||
.filter(|metadata| metadata.is_file())
|
.filter(|metadata| metadata.is_file())
|
||||||
.fold(0, |acc, m| acc + m.len());
|
.fold(0, |acc, m| acc + m.len());
|
||||||
|
|
||||||
let last_update = data
|
let last_update = data.last_update(&reader)?;
|
||||||
.last_update(&reader)
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(web::Json(StatsResult {
|
Ok(web::Json(StatsResult {
|
||||||
database_size,
|
database_size,
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
use std::collections::BTreeSet;
|
|
||||||
|
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{delete, get, post, web, HttpResponse};
|
use actix_web::{delete, get, post, web, HttpResponse};
|
||||||
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
use crate::error::ResponseError;
|
use crate::error::ResponseError;
|
||||||
use crate::routes::{IndexParam, IndexUpdateResponse};
|
use crate::routes::{IndexParam, IndexUpdateResponse};
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
#[get("/indexes/{index_uid}/settings/stop-words")]
|
#[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
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
let stop_words_fst = index.main.stop_words_fst(&reader)?;
|
||||||
.main_read_txn()
|
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)
|
|
||||||
.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(HttpResponse::Ok().json(stop_words))
|
Ok(HttpResponse::Ok().json(stop_words))
|
||||||
}
|
}
|
||||||
@ -36,27 +27,20 @@ pub async fn update(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<BTreeSet<String>>,
|
body: web::Json<BTreeSet<String>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
stop_words: UpdateState::Update(body.into_inner()),
|
stop_words: UpdateState::Update(body.into_inner()),
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.update_write_txn()
|
writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -65,27 +49,20 @@ pub async fn update(
|
|||||||
pub async fn delete(
|
pub async fn delete(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
stop_words: UpdateState::Clear,
|
stop_words: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.update_write_txn()
|
writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use actix_web as aweb;
|
|
||||||
use actix_web::{delete, get, post, web, HttpResponse};
|
use actix_web::{delete, get, post, web, HttpResponse};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
|
||||||
@ -10,41 +9,27 @@ use crate::routes::{IndexParam, IndexUpdateResponse};
|
|||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
#[get("/indexes/{index_uid}/settings/synonyms")]
|
#[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
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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
|
let reader = data.db.main_read_txn()?;
|
||||||
.db
|
|
||||||
.main_read_txn()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
let synonyms_fst = index
|
let synonyms_fst = index.main.synonyms_fst(&reader)?.unwrap_or_default();
|
||||||
.main
|
let synonyms_list = synonyms_fst.stream().into_strs()?;
|
||||||
.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 mut synonyms = IndexMap::new();
|
let mut synonyms = IndexMap::new();
|
||||||
|
|
||||||
let index_synonyms = &index.synonyms;
|
let index_synonyms = &index.synonyms;
|
||||||
|
|
||||||
for synonym in synonyms_list {
|
for synonym in synonyms_list {
|
||||||
let alternative_list = index_synonyms
|
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
|
||||||
.synonyms(&reader, synonym.as_bytes())
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
if let Some(list) = alternative_list {
|
if let Some(list) = alternative_list {
|
||||||
let list = list
|
let list = list.stream().into_strs()?;
|
||||||
.stream()
|
|
||||||
.into_strs()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
synonyms.insert(synonym, list);
|
synonyms.insert(synonym, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,27 +42,20 @@ pub async fn update(
|
|||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<BTreeMap<String, Vec<String>>>,
|
body: web::Json<BTreeMap<String, Vec<String>>>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
synonyms: UpdateState::Update(body.into_inner()),
|
synonyms: UpdateState::Update(body.into_inner()),
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.update_write_txn()
|
writer.commit()?;
|
||||||
.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()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -86,28 +64,21 @@ pub async fn update(
|
|||||||
pub async fn delete(
|
pub async fn delete(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
) -> aweb::Result<HttpResponse> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let index = data
|
||||||
.db
|
.db
|
||||||
.open_index(&path.index_uid)
|
.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 {
|
let settings = SettingsUpdate {
|
||||||
synonyms: UpdateState::Clear,
|
synonyms: UpdateState::Clear,
|
||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut writer = data
|
let mut writer = data.db.update_write_txn()?;
|
||||||
.db
|
let update_id = index.settings_update(&mut writer, settings)?;
|
||||||
.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
|
writer.commit()?;
|
||||||
.commit()
|
|
||||||
.map_err(|err| ResponseError::Internal(err.to_string()))?;
|
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user