clippy + fmt

This commit is contained in:
Quentin de Quelen 2020-04-10 19:05:05 +02:00 committed by qdequele
parent 22fbff98d4
commit 6a1f73a304
No known key found for this signature in database
GPG Key ID: B3F0A000EBF11745
17 changed files with 633 additions and 339 deletions

View File

@ -135,7 +135,7 @@ impl Data {
let db = Arc::new(Database::open_or_create(opt.db_path).unwrap());
let mut api_keys = ApiKeys {
master: opt.master_key.clone(),
master: opt.master_key,
private: None,
public: None,
};

View File

@ -1,8 +1,9 @@
use std::fmt;
use serde_json::json;
use actix_web as aweb;
use actix_http::ResponseBuilder;
use actix_web as aweb;
use actix_web::http::StatusCode;
use serde_json::json;
#[derive(Debug)]
pub enum ResponseError {

View File

@ -1,14 +1,14 @@
use std::{env, thread};
use actix_web::middleware::Logger;
use actix_web::{web, App, HttpServer};
use log::info;
use main_error::MainError;
use structopt::StructOpt;
use actix_web::middleware::Logger;
use actix_web::{web, HttpServer, App};
use meilisearch_http::data::Data;
use meilisearch_http::option::Opt;
use meilisearch_http::routes;
use meilisearch_http::routes::index_update_callback;
use structopt::StructOpt;
mod analytics;
@ -30,7 +30,7 @@ async fn main() -> Result<(), MainError> {
.into(),
);
}
},
}
"development" => {
env_logger::from_env(env_logger::Env::default().default_filter_or("info")).init();
}
@ -50,7 +50,7 @@ async fn main() -> Result<(), MainError> {
print_launch_resume(&opt, &data);
HttpServer::new(move ||
HttpServer::new(move || {
App::new()
.wrap(Logger::default())
.app_data(web::Data::new(data.clone()))
@ -103,10 +103,10 @@ async fn main() -> Result<(), MainError> {
.service(routes::stats::get_sys_info_pretty)
.service(routes::health::get_health)
.service(routes::health::change_healthyness)
)
.bind(opt.http_addr)?
.run()
.await?;
})
.bind(opt.http_addr)?
.run()
.await?;
Ok(())
}

View File

@ -1,20 +1,21 @@
use std::collections::BTreeSet;
use actix_web as aweb;
use actix_web::{delete, get, post, put, web, HttpResponse};
use indexmap::IndexMap;
use serde::Deserialize;
use serde_json::Value;
use actix_web::{web, get, post, put, delete, HttpResponse};
use actix_web as aweb;
use crate::error::ResponseError;
use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
use crate::routes::{IndexUpdateResponse, IndexParam};
type Document = IndexMap<String, Value>;
#[derive(Default, Deserialize)]
pub struct DocumentParam {
index_uid: String,
document_id: String
document_id: String,
}
#[get("/indexes/{index_uid}/documents/{document_id}")]
@ -22,14 +23,19 @@ pub async fn get_document(
data: web::Data<Data>,
path: web::Path<DocumentParam>,
) -> aweb::Result<web::Json<Document>> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let response = index.document::<Document, String>(&reader, None, document_id)
let response = index
.document::<Document, String>(&reader, None, document_id)
.map_err(|_| ResponseError::DocumentNotFound(path.document_id.clone()))?
.ok_or(ResponseError::DocumentNotFound(path.document_id.clone()))?;
@ -41,26 +47,31 @@ pub async fn delete_document(
data: web::Data<Data>,
path: web::Path<DocumentParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let document_id = meilisearch_core::serde::compute_document_id(path.document_id.clone());
let mut update_writer = data.db.update_write_txn()
let mut update_writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut documents_deletion = index.documents_deletion();
documents_deletion.delete_document_by_id(document_id);
let update_id = documents_deletion.finalize(&mut update_writer)
let update_id = documents_deletion
.finalize(&mut update_writer)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
update_writer.commit()
update_writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
}
#[derive(Default, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct BrowseQuery {
@ -75,14 +86,17 @@ pub async fn get_all_documents(
path: web::Path<IndexParam>,
params: web::Query<BrowseQuery>,
) -> aweb::Result<web::Json<Vec<Document>>> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let offset = params.offset.unwrap_or(0);
let limit = params.limit.unwrap_or(20);
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let documents_ids: Result<BTreeSet<_>, _> = index
@ -93,10 +107,11 @@ pub async fn get_all_documents(
.take(limit)
.collect();
let documents_ids = documents_ids
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let documents_ids = documents_ids.map_err(|err| ResponseError::Internal(err.to_string()))?;
let attributes = params.attributes_to_retrieve.clone()
let attributes = params
.attributes_to_retrieve
.clone()
.map(|a| a.split(',').map(|a| a.to_string()).collect());
let mut response_body = Vec::<Document>::new();
@ -129,39 +144,48 @@ async fn update_multiple_documents(
path: web::Path<IndexParam>,
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>,
is_partial: bool
is_partial: bool,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ok_or(ResponseError::Internal("Impossible to retrieve the schema".to_string()))?;
.ok_or(ResponseError::Internal(
"Impossible to retrieve the schema".to_string(),
))?;
if schema.primary_key().is_none() {
let id = match params.primary_key.clone() {
Some(id) => id,
None => {
body.first()
.and_then(|docs| find_primary_key(docs))
.ok_or(ResponseError::BadRequest("Impossible to infer the primary key".to_string()))?
}
None => body.first().and_then(|docs| find_primary_key(docs)).ok_or(
ResponseError::BadRequest("Impossible to infer the primary key".to_string()),
)?,
};
let mut writer = data.db.main_write_txn()
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
schema.set_primary_key(&id)
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
index.main.put_schema(&mut writer, &schema)
index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
}
@ -175,11 +199,15 @@ async fn update_multiple_documents(
document_addition.update_document(document);
}
let mut update_writer = data.db.update_write_txn()
let mut update_writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = document_addition.finalize(&mut update_writer)
let update_id = document_addition
.finalize(&mut update_writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
update_writer.commit()
update_writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -190,7 +218,7 @@ pub async fn add_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>
body: web::Json<Vec<Document>>,
) -> aweb::Result<HttpResponse> {
update_multiple_documents(data, path, params, body, false).await
}
@ -200,7 +228,7 @@ pub async fn update_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
params: web::Query<UpdateDocumentsQuery>,
body: web::Json<Vec<Document>>
body: web::Json<Vec<Document>>,
) -> aweb::Result<HttpResponse> {
update_multiple_documents(data, path, params, body, true).await
}
@ -209,13 +237,16 @@ pub async fn update_documents(
pub async fn delete_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Vec<Value>>
body: web::Json<Vec<Value>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut documents_deletion = index.documents_deletion();
@ -227,10 +258,12 @@ pub async fn delete_documents(
}
}
let update_id = documents_deletion.finalize(&mut writer)
let update_id = documents_deletion
.finalize(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -241,17 +274,22 @@ pub async fn clear_all_documents(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.clear_all(&mut writer)
let update_id = index
.clear_all(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))

View File

@ -1,17 +1,17 @@
use crate::error::ResponseError;
use actix_web::{web, get, put, HttpResponse};
use actix_web as aweb;
use crate::Data;
use actix_web as aweb;
use actix_web::{get, put, web, HttpResponse};
use heed::types::{Str, Unit};
use serde::Deserialize;
const UNHEALTHY_KEY: &str = "_is_unhealthy";
#[get("/health")]
pub async fn get_health(
data: web::Data<Data>,
) -> aweb::Result<HttpResponse> {
let reader = data.db.main_read_txn()
pub async fn get_health(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let common_store = data.db.common_store();
@ -23,29 +23,33 @@ pub async fn get_health(
Ok(HttpResponse::Ok().finish())
}
pub async fn set_healthy(
data: web::Data<Data>,
) -> aweb::Result<HttpResponse> {
let mut writer = data.db.main_write_txn()
pub async fn set_healthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let common_store = data.db.common_store();
common_store.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)
common_store
.delete::<_, Str>(&mut writer, UNHEALTHY_KEY)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Ok().finish())
}
pub async fn set_unhealthy(
data: web::Data<Data>,
) -> aweb::Result<HttpResponse> {
let mut writer = data.db.main_write_txn()
pub async fn set_unhealthy(data: web::Data<Data>) -> aweb::Result<HttpResponse> {
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let common_store = data.db.common_store();
common_store.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())
common_store
.put::<_, Str, Unit>(&mut writer, UNHEALTHY_KEY, &())
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Ok().finish())

View File

@ -1,14 +1,14 @@
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use chrono::{DateTime, Utc};
use log::error;
use meilisearch_core::UpdateStatus;
use rand::seq::SliceRandom;
use serde::{Deserialize, Serialize};
use actix_web::{web, get, post, delete, HttpResponse};
use actix_web as aweb;
use meilisearch_core::UpdateStatus;
use crate::error::ResponseError;
use crate::Data;
use crate::routes::IndexParam;
use crate::Data;
fn generate_uid() -> String {
let mut rng = rand::thread_rng();
@ -30,11 +30,10 @@ pub struct IndexResponse {
}
#[get("/indexes")]
pub async fn list_indexes(
data: web::Data<Data>,
) -> aweb::Result<web::Json<Vec<IndexResponse>>> {
let reader = data.db.main_read_txn()
pub async fn list_indexes(data: web::Data<Data>) -> aweb::Result<web::Json<Vec<IndexResponse>>> {
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut response_body = Vec::new();
@ -44,15 +43,27 @@ pub async fn list_indexes(
match index {
Some(index) => {
let name = index.main.name(&reader)
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the name of an index".to_string()))?;
let created_at = index.main.created_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the create date of an index".to_string()))?;
let updated_at = index.main.updated_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the last update date of an index".to_string()))?;
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
))?;
let primary_key = match index.main.schema(&reader) {
Ok(Some(schema)) => match schema.primary_key() {
@ -86,22 +97,37 @@ pub async fn get_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<web::Json<IndexResponse>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let name = index.main.name(&reader)
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the name of an index".to_string()))?;
let created_at = index.main.created_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the create date of an index".to_string()))?;
let updated_at = index.main.updated_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the last update date of an index".to_string()))?;
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
))?;
let primary_key = match index.main.schema(&reader) {
Ok(Some(schema)) => match schema.primary_key() {
@ -131,11 +157,12 @@ pub struct IndexCreateRequest {
#[post("/indexes")]
pub async fn create_index(
data: web::Data<Data>,
body: web::Json<IndexCreateRequest>
body: web::Json<IndexCreateRequest>,
) -> aweb::Result<web::Json<IndexResponse>> {
if let (None, None) = (body.name.clone(), body.uid.clone()) {
return Err(ResponseError::BadRequest("Index creation must have an uid".to_string()).into());
return Err(
ResponseError::BadRequest("Index creation must have an uid".to_string()).into(),
);
}
let uid = match body.uid.clone() {
@ -157,14 +184,20 @@ pub async fn create_index(
},
};
let created_index = data.db.create_index(&uid)
let created_index = data
.db
.create_index(&uid)
.map_err(|e| ResponseError::CreateIndex(e.to_string()))?;
let mut writer = data.db.main_write_txn()
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let name = body.name.clone().unwrap_or(uid.clone());
created_index.main.put_name(&mut writer, &name)
created_index
.main
.put_name(&mut writer, &name)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
let created_at = created_index
@ -180,16 +213,23 @@ pub async fn create_index(
.ok_or(ResponseError::Internal("".to_string()))?;
if let Some(id) = body.primary_key.clone() {
if let Some(mut schema) = created_index.main.schema(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))? {
schema.set_primary_key(&id)
if let Some(mut schema) = created_index
.main
.schema(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
{
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
created_index.main.put_schema(&mut writer, &schema)
created_index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
}
}
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(web::Json(IndexResponse {
@ -222,55 +262,85 @@ pub struct UpdateIndexResponse {
pub async fn update_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<IndexCreateRequest>
body: web::Json<IndexCreateRequest>,
) -> aweb::Result<web::Json<IndexResponse>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data
.db
.main_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
if let Some(name) = body.name.clone() {
index.main.put_name(&mut writer, &name)
index
.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(mut schema) = index.main.schema(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))? {
if let Some(mut schema) = index
.main
.schema(&writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?
{
match schema.primary_key() {
Some(_) => {
return Err(ResponseError::BadRequest("The primary key cannot be updated".to_string()).into());
return Err(ResponseError::BadRequest(
"The primary key cannot be updated".to_string(),
)
.into());
}
None => {
schema
.set_primary_key(&id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
index.main.put_schema(&mut writer, &schema)
index
.main
.put_schema(&mut writer, &schema)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
}
}
}
}
index.main.put_updated_at(&mut writer)
index
.main
.put_updated_at(&mut writer)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let name = index.main.name(&reader)
let name = index
.main
.name(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the name of an index".to_string()))?;
let created_at = index.main.created_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the name of an index".to_string(),
))?;
let created_at = index
.main
.created_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the create date of an index".to_string()))?;
let updated_at = index.main.updated_at(&reader)
.ok_or(ResponseError::Internal(
"Impossible to get the create date of an index".to_string(),
))?;
let updated_at = index
.main
.updated_at(&reader)
.map_err(|e| ResponseError::Internal(e.to_string()))?
.ok_or(ResponseError::Internal("Impossible to get the last update date of an index".to_string()))?;
.ok_or(ResponseError::Internal(
"Impossible to get the last update date of an index".to_string(),
))?;
let primary_key = match index.main.schema(&reader) {
Ok(Some(schema)) => match schema.primary_key() {
@ -294,8 +364,8 @@ pub async fn delete_index(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
data.db.delete_index(&path.index_uid)
data.db
.delete_index(&path.index_uid)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
HttpResponse::NoContent().await
@ -304,7 +374,7 @@ pub async fn delete_index(
#[derive(Default, Deserialize)]
pub struct UpdateParam {
index_uid: String,
update_id: u64
update_id: u64,
}
#[get("/indexes/{index_uid}/updates/{update_id}")]
@ -312,19 +382,23 @@ pub async fn get_update_status(
data: web::Data<Data>,
path: web::Path<UpdateParam>,
) -> aweb::Result<web::Json<UpdateStatus>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.update_read_txn()
let reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let status = index.update_status(&reader, path.update_id)
let status = index
.update_status(&reader, path.update_id)
.map_err(|e| ResponseError::Internal(e.to_string()))?;
match status {
Some(status) => Ok(web::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)).into()),
}
}
@ -333,14 +407,18 @@ pub async fn get_all_updates_status(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<web::Json<Vec<UpdateStatus>>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.update_read_txn()
let reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let response = index.all_updates_status(&reader)
let response = index
.all_updates_status(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(web::Json(response))

View File

@ -1,8 +1,7 @@
use crate::Data;
use actix_web::{web, get};
use actix_web::{get, web};
use serde::Serialize;
#[derive(Default, Serialize)]
pub struct KeysResponse {
private: Option<String>,
@ -10,11 +9,9 @@ pub struct KeysResponse {
}
#[get("/keys")]
pub async fn list(
data: web::Data<Data>,
) -> web::Json<KeysResponse> {
pub async fn list(data: web::Data<Data>) -> web::Json<KeysResponse> {
let api_keys = data.api_keys.clone();
web::Json(KeysResponse{
web::Json(KeysResponse {
private: api_keys.private,
public: api_keys.public,
})

View File

@ -1,7 +1,7 @@
use actix_web::{get, HttpResponse};
use serde::{Serialize, Deserialize};
use log::error;
use meilisearch_core::ProcessedUpdateResult;
use serde::{Deserialize, Serialize};
use crate::Data;
@ -10,14 +10,14 @@ pub mod health;
pub mod index;
pub mod key;
pub mod search;
pub mod stats;
pub mod setting;
pub mod stats;
pub mod stop_words;
pub mod synonym;
#[derive(Default, Deserialize)]
pub struct IndexParam {
index_uid: String
index_uid: String,
}
#[derive(Default, Serialize)]
@ -28,9 +28,7 @@ pub struct IndexUpdateResponse {
impl IndexUpdateResponse {
pub fn with_id(update_id: u64) -> Self {
Self {
update_id,
}
Self { update_id }
}
}
@ -48,7 +46,6 @@ pub async fn load_css() -> HttpResponse {
.body(include_str!("../../public/bulma.min.css").to_string())
}
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {
if status.error.is_some() {
return;
@ -82,7 +79,6 @@ pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpda
}
}
// pub fn load_routes(app: &mut tide::Server<Data>) {
// app.at("/").get(|_| async {
// tide::Response::new(200)

View File

@ -4,15 +4,15 @@ use std::time::Duration;
use log::warn;
use meilisearch_core::Index;
use actix_web as aweb;
use actix_web::{get, post, web};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use serde::{Deserialize, Serialize};
use actix_web::{web, get, post};
use actix_web as aweb;
use crate::error::ResponseError;
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit, SearchResult};
use crate::Data;
use crate::routes::IndexParam;
use crate::Data;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
@ -35,18 +35,23 @@ pub async fn search_with_url_query(
path: web::Path<IndexParam>,
params: web::Query<SearchQuery>,
) -> aweb::Result<web::Json<SearchResult>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.ok_or(ResponseError::Internal("Impossible to retrieve the schema".to_string()))?;
.ok_or(ResponseError::Internal(
"Impossible to retrieve the schema".to_string(),
))?;
let mut search_builder = index.new_search(params.q.clone());
@ -182,7 +187,6 @@ pub async fn search_multi_index(
data: web::Data<Data>,
body: web::Json<SearchMultiBody>,
) -> aweb::Result<web::Json<SearchMultiBodyResponse>> {
let mut index_list = body.clone().indexes;
for index in index_list.clone() {
@ -203,7 +207,6 @@ pub async fn search_multi_index(
}
}
let par_body = body.clone();
let responses_per_index: Vec<(String, SearchResult)> = index_list
.into_par_iter()

View File

@ -1,42 +1,58 @@
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES};
use std::collections::{BTreeMap, BTreeSet, HashSet};
use actix_web::{web, get, post, delete, HttpResponse};
use actix_web as aweb;
use crate::error::{ResponseError};
use crate::error::ResponseError;
use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
use crate::routes::{IndexUpdateResponse, IndexParam};
#[post("/indexes/{index_uid}/settings")]
pub async fn update_all(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words_fst = index.main.stop_words_fst(&reader)
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()
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 synonyms_fst = index.main.synonyms_fst(&reader)
let synonyms_fst = index
.main
.synonyms_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let synonyms_list = synonyms_fst.stream().into_strs()
let synonyms_list = synonyms_fst
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut synonyms = BTreeMap::new();
let index_synonyms = &index.synonyms;
for synonym in synonyms_list {
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())
let alternative_list = index_synonyms
.synonyms(&reader, synonym.as_bytes())
.map_err(|err| ResponseError::Internal(err.to_string()))?;
if let Some(list) = alternative_list {
let list = list.stream().into_strs()
let list = list
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
synonyms.insert(synonym, list);
}
@ -51,10 +67,14 @@ pub async fn update_all(
.map(|r| r.to_string())
.collect();
let distinct_attribute = index.main.distinct_attribute(&reader)
let distinct_attribute = index
.main
.distinct_attribute(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let searchable_attributes = schema.clone().map(|s| {
@ -92,16 +112,24 @@ pub async fn get_all(
path: web::Path<IndexParam>,
body: web::Json<Settings>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = body.into_inner().into_update()
let settings = body
.into_inner()
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -112,9 +140,13 @@ pub async fn delete_all(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = SettingsUpdate {
@ -128,9 +160,11 @@ pub async fn delete_all(
accept_new_fields: UpdateState::Clear,
};
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -141,10 +175,14 @@ pub async fn get_rules(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let ranking_rules = index
.main
@ -164,7 +202,9 @@ pub async fn update_rules(
path: web::Path<IndexParam>,
body: web::Json<Option<Vec<String>>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = Settings {
@ -172,13 +212,18 @@ pub async fn update_rules(
..Settings::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings.into_update()
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -189,9 +234,13 @@ pub async fn delete_rules(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = SettingsUpdate {
@ -199,10 +248,12 @@ pub async fn delete_rules(
..SettingsUpdate::default()
};
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -213,11 +264,17 @@ pub async fn get_distinct(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let distinct_attribute = index.main.distinct_attribute(&reader)
let distinct_attribute = index
.main
.distinct_attribute(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Ok().json(distinct_attribute))
@ -229,7 +286,9 @@ pub async fn update_distinct(
path: web::Path<IndexParam>,
body: web::Json<Option<String>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = Settings {
@ -237,13 +296,18 @@ pub async fn update_distinct(
..Settings::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings.into_update()
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -254,21 +318,27 @@ pub async fn delete_distinct(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let mut writer = data.db.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = SettingsUpdate {
distinct_attribute: UpdateState::Clear,
..SettingsUpdate::default()
};
let update_id = index.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
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)))
}
@ -278,11 +348,17 @@ pub async fn get_searchable(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let searchable_attributes: Option<Vec<String>> =
schema.map(|s| s.indexed_name().iter().map(|i| (*i).to_string()).collect());
@ -296,7 +372,9 @@ pub async fn update_searchable(
path: web::Path<IndexParam>,
body: web::Json<Option<Vec<String>>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = Settings {
@ -304,13 +382,18 @@ pub async fn update_searchable(
..Settings::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings.into_update()
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -321,7 +404,9 @@ pub async fn delete_searchable(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -329,11 +414,15 @@ pub async fn delete_searchable(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -344,12 +433,18 @@ pub async fn get_displayed(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let displayed_attributes: Option<HashSet<String>> = schema.map(|s| {
@ -368,7 +463,9 @@ pub async fn update_displayed(
path: web::Path<IndexParam>,
body: web::Json<Option<HashSet<String>>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = Settings {
@ -376,13 +473,18 @@ pub async fn update_displayed(
..Settings::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings.into_update()
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -393,7 +495,9 @@ pub async fn delete_displayed(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -401,12 +505,16 @@ pub async fn delete_displayed(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut writer = data
.db
.update_write_txn()
.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)))
}
@ -416,12 +524,18 @@ pub async fn get_accept_new_fields(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let schema = index.main.schema(&reader)
let schema = index
.main
.schema(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let accept_new_fields = schema.map(|s| s.accept_new_fields());
@ -435,7 +549,9 @@ pub async fn update_accept_new_fields(
path: web::Path<IndexParam>,
body: web::Json<Option<bool>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = Settings {
@ -443,13 +559,18 @@ pub async fn update_accept_new_fields(
..Settings::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let settings = settings.into_update()
let settings = settings
.into_update()
.map_err(|e| ResponseError::BadRequest(e.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))

View File

@ -1,7 +1,7 @@
use std::collections::HashMap;
use actix_web as aweb;
use actix_web::{web, get};
use actix_web::{get, web};
use chrono::{DateTime, Utc};
use log::error;
use pretty_bytes::converter::convert;
@ -9,9 +9,9 @@ use serde::Serialize;
use sysinfo::{NetworkExt, ProcessExt, ProcessorExt, System, SystemExt};
use walkdir::WalkDir;
use crate::Data;
use crate::error::ResponseError;
use crate::routes::IndexParam;
use crate::Data;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
@ -26,20 +26,30 @@ pub async fn index_stats(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<web::Json<IndexStatsResponse>> {
let index = data.db.open_index(path.index_uid.clone())
let index = data
.db
.open_index(path.index_uid.clone())
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let number_of_documents = index.main.number_of_documents(&reader)
let number_of_documents = index
.main
.number_of_documents(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let fields_frequency = index.main.fields_frequency(&reader)
let fields_frequency = index
.main
.fields_frequency(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let update_reader = data.db.update_read_txn()
let update_reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let is_indexing = data
@ -63,15 +73,16 @@ pub struct StatsResult {
}
#[get("/stats")]
pub async fn get_stats(
data: web::Data<Data>,
) -> aweb::Result<web::Json<StatsResult>> {
pub async fn get_stats(data: web::Data<Data>) -> aweb::Result<web::Json<StatsResult>> {
let mut index_list = HashMap::new();
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_reader = data.db.update_read_txn()
let update_reader = data
.db
.update_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let indexes_set = data.db.indexes_uids();
@ -79,10 +90,14 @@ pub async fn get_stats(
let index = data.db.open_index(&index_uid);
match index {
Some(index) => {
let number_of_documents = index.main.number_of_documents(&reader)
let number_of_documents = index
.main
.number_of_documents(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let fields_frequency = index.main.fields_frequency(&reader)
let fields_frequency = index
.main
.fields_frequency(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
@ -112,7 +127,8 @@ pub async fn get_stats(
.filter(|metadata| metadata.is_file())
.fold(0, |acc, m| acc + m.len());
let last_update = data.last_update(&reader)
let last_update = data
.last_update(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(web::Json(StatsResult {
@ -200,9 +216,7 @@ impl SysInfo {
}
#[get("/sys-info")]
pub async fn get_sys_info(
data: web::Data<Data>,
) -> web::Json<SysInfo> {
pub async fn get_sys_info(data: web::Data<Data>) -> web::Json<SysInfo> {
let mut sys = System::new();
let mut info = SysInfo::new();
@ -216,11 +230,13 @@ pub async fn get_sys_info(
info.global.used_memory = sys.get_used_memory();
info.global.total_swap = sys.get_total_swap();
info.global.used_swap = sys.get_used_swap();
info.global.input_data = sys.get_networks()
info.global.input_data = sys
.get_networks()
.into_iter()
.map(|(_, n)| n.get_received())
.sum::<u64>();
info.global.output_data = sys.get_networks()
info.global.output_data = sys
.get_networks()
.into_iter()
.map(|(_, n)| n.get_transmitted())
.sum::<u64>();
@ -294,11 +310,8 @@ impl SysInfoPretty {
}
}
#[get("/sys-info/pretty")]
pub async fn get_sys_info_pretty(
data: web::Data<Data>,
) -> web::Json<SysInfoPretty> {
pub async fn get_sys_info_pretty(data: web::Data<Data>) -> web::Json<SysInfoPretty> {
let mut sys = System::new();
let mut info = SysInfoPretty::new();
@ -316,8 +329,18 @@ pub async fn get_sys_info_pretty(
info.global.used_memory = convert(sys.get_used_memory() as f64 * 1024.0);
info.global.total_swap = convert(sys.get_total_swap() as f64 * 1024.0);
info.global.used_swap = convert(sys.get_used_swap() as f64 * 1024.0);
info.global.input_data = convert(sys.get_networks().into_iter().map(|(_, n)| n.get_received()).sum::<u64>() as f64);
info.global.output_data = convert(sys.get_networks().into_iter().map(|(_, n)| n.get_transmitted()).sum::<u64>() as f64);
info.global.input_data = convert(
sys.get_networks()
.into_iter()
.map(|(_, n)| n.get_received())
.sum::<u64>() as f64,
);
info.global.output_data = convert(
sys.get_networks()
.into_iter()
.map(|(_, n)| n.get_transmitted())
.sum::<u64>() as f64,
);
if let Some(process) = sys.get_process(data.server_pid) {
info.process.memory = convert(process.memory() as f64 * 1024.0);

View File

@ -1,25 +1,31 @@
use std::collections::BTreeSet;
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use actix_web::{web, get, post, delete, HttpResponse};
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use crate::error::{ResponseError};
use crate::error::ResponseError;
use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
use crate::routes::{IndexUpdateResponse, IndexParam};
#[get("/indexes/{index_uid}/settings/stop-words")]
pub async fn get(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
pub async fn get(data: web::Data<Data>, path: web::Path<IndexParam>) -> aweb::Result<HttpResponse> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let stop_words_fst = index.main.stop_words_fst(&reader)
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()
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))
@ -31,7 +37,9 @@ pub async fn update(
path: web::Path<IndexParam>,
body: web::Json<BTreeSet<String>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -39,11 +47,15 @@ pub async fn update(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -54,7 +66,9 @@ pub async fn delete(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -62,11 +76,15 @@ pub async fn delete(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))

View File

@ -1,29 +1,34 @@
use std::collections::BTreeMap;
use actix_web as aweb;
use actix_web::{delete, get, post, web, HttpResponse};
use indexmap::IndexMap;
use meilisearch_core::settings::{SettingsUpdate, UpdateState};
use actix_web::{web, get, post, delete, HttpResponse};
use actix_web as aweb;
use crate::error::{ResponseError};
use crate::error::ResponseError;
use crate::routes::{IndexParam, IndexUpdateResponse};
use crate::Data;
use crate::routes::{IndexUpdateResponse, IndexParam};
#[get("/indexes/{index_uid}/settings/synonyms")]
pub async fn get(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
pub async fn get(data: web::Data<Data>, path: web::Path<IndexParam>) -> aweb::Result<HttpResponse> {
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let reader = data.db.main_read_txn()
let reader = data
.db
.main_read_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let synonyms_fst = index.main.synonyms_fst(&reader)
let synonyms_fst = index
.main
.synonyms_fst(&reader)
.map_err(|err| ResponseError::Internal(err.to_string()))?
.unwrap_or_default();
let synonyms_list = synonyms_fst.stream().into_strs()
let synonyms_list = synonyms_fst
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let mut synonyms = IndexMap::new();
@ -31,11 +36,14 @@ pub async fn get(
let index_synonyms = &index.synonyms;
for synonym in synonyms_list {
let alternative_list = index_synonyms.synonyms(&reader, synonym.as_bytes())
let alternative_list = index_synonyms
.synonyms(&reader, synonym.as_bytes())
.map_err(|err| ResponseError::Internal(err.to_string()))?;
if let Some(list) = alternative_list {
let list = list.stream().into_strs()
let list = list
.stream()
.into_strs()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
synonyms.insert(synonym, list);
}
@ -50,7 +58,9 @@ pub async fn update(
path: web::Path<IndexParam>,
body: web::Json<BTreeMap<String, Vec<String>>>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -58,11 +68,15 @@ pub async fn update(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
@ -73,7 +87,9 @@ pub async fn delete(
data: web::Data<Data>,
path: web::Path<IndexParam>,
) -> aweb::Result<HttpResponse> {
let index = data.db.open_index(&path.index_uid)
let index = data
.db
.open_index(&path.index_uid)
.ok_or(ResponseError::IndexNotFound(path.index_uid.clone()))?;
let settings = SettingsUpdate {
@ -81,12 +97,16 @@ pub async fn delete(
..SettingsUpdate::default()
};
let mut writer = data.db.update_write_txn()
let mut writer = data
.db
.update_write_txn()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
let update_id = index.settings_update(&mut writer, settings)
let update_id = index
.settings_update(&mut writer, settings)
.map_err(|err| ResponseError::Internal(err.to_string()))?;
writer.commit()
writer
.commit()
.map_err(|err| ResponseError::Internal(err.to_string()))?;
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))

View File

@ -91,11 +91,11 @@ fn check_add_documents_with_nested_null() {
// 2 - Add a document that contains a null in a nested object
let body = json!([{
"id": 0,
"foo": {
let body = json!([{
"id": 0,
"foo": {
"bar": null
}
}
}]);
let url = "/indexes/tasks/documents";
@ -126,9 +126,9 @@ fn check_add_documents_with_nested_sequence() {
// 2 - Add a document that contains a seq in a nested object
let body = json!([{
"id": 0,
"foo": {
let body = json!([{
"id": 0,
"foo": {
"bar": [123,456],
"fez": [{
"id": 255,

View File

@ -660,7 +660,7 @@ fn check_add_documents_without_primary_key() {
}
#[test]
fn check_first_update_should_bring_up_processed_status_after_first_docs_addition(){
fn check_first_update_should_bring_up_processed_status_after_first_docs_addition() {
let mut server = common::Server::with_uid("movies");
let body = json!({
@ -678,11 +678,11 @@ fn check_first_update_should_bring_up_processed_status_after_first_docs_addition
// 2. Index the documents from movies.json, present inside of assets directory
server.add_or_replace_multiple_documents(body);
// 3. Fetch the status of the indexing done above.
let (response, status_code) = server.get_all_updates_status();
// 4. Verify the fetch is successful and indexing status is 'processed'
assert_eq!(status_code, 200);
assert_eq!(response[0]["status"], "processed");
assert_eq!(response[0]["status"], "processed");
}

View File

@ -289,10 +289,9 @@ fn index_new_fields_false_then_true() {
assert_json_eq!(response, expected);
}
// Fix issue https://github.com/meilisearch/MeiliSearch/issues/518
#[test]
fn accept_new_fields_does_not_take_into_account_the_primary_key () {
fn accept_new_fields_does_not_take_into_account_the_primary_key() {
let mut server = common::Server::with_uid("movies");
// 1 - Create an index with no primary-key

View File

@ -148,10 +148,7 @@ fn write_custom_ranking_and_index_documents() {
// 1 - Add ranking rules with one custom ranking on a string
let body = json!([
"asc(title)",
"typo"
]);
let body = json!(["asc(title)", "typo"]);
server.update_ranking_rules(body);
@ -184,5 +181,4 @@ fn write_custom_ranking_and_index_documents() {
assert_eq!(status_code, 200);
assert_json_eq!(response, expected, ordered: false);
}