mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-23 13:24:27 +01:00
create an helper to allow to delete the index on error
This commit is contained in:
parent
0a67248bfe
commit
bfe3bb0eeb
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1914,7 +1914,8 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.1.3"
|
version = "2.1.3"
|
||||||
source = "git+https://github.com/pest-parser/pest.git?rev=51fd1d49f1041f7839975664ef71fe15c7dcaf67#51fd1d49f1041f7839975664ef71fe15c7dcaf67"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ucd-trie",
|
"ucd-trie",
|
||||||
]
|
]
|
||||||
@ -1922,8 +1923,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.1.3"
|
version = "2.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/MarinPostma/pest.git?tag=meilisearch-patch1#e1031ad0134d5e9893c470dbea50811b2b746926"
|
||||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ucd-trie",
|
"ucd-trie",
|
||||||
]
|
]
|
||||||
|
@ -3,9 +3,10 @@ use std::ops::Deref;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use meilisearch_core::{Database, DatabaseOptions};
|
use meilisearch_core::{Database, DatabaseOptions, Index};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
|
||||||
|
use crate::error::{Error as MSError, ResponseError};
|
||||||
use crate::index_update_callback;
|
use crate::index_update_callback;
|
||||||
use crate::option::Opt;
|
use crate::option::Opt;
|
||||||
|
|
||||||
@ -102,4 +103,60 @@ impl Data {
|
|||||||
|
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_index(&self, uid: &str) -> Result<Index, ResponseError> {
|
||||||
|
if !uid
|
||||||
|
.chars()
|
||||||
|
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
||||||
|
{
|
||||||
|
return Err(MSError::InvalidIndexUid.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let created_index = self.db.create_index(&uid).map_err(|e| match e {
|
||||||
|
meilisearch_core::Error::IndexAlreadyExists => e.into(),
|
||||||
|
_ => ResponseError::from(MSError::create_index(e)),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.db.main_write::<_, _, ResponseError>(|mut writer| {
|
||||||
|
created_index.main.put_name(&mut writer, uid)?;
|
||||||
|
|
||||||
|
created_index
|
||||||
|
.main
|
||||||
|
.created_at(&writer)?
|
||||||
|
.ok_or(MSError::internal("Impossible to read created at"))?;
|
||||||
|
|
||||||
|
created_index
|
||||||
|
.main
|
||||||
|
.updated_at(&writer)?
|
||||||
|
.ok_or(MSError::internal("Impossible to read updated at"))?;
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(created_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_or_create_index<F, R>(&self, uid: &str, f: F) -> Result<R, ResponseError>
|
||||||
|
where
|
||||||
|
F: FnOnce(&Index) -> Result<R, ResponseError>,
|
||||||
|
{
|
||||||
|
let mut index_has_been_created = false;
|
||||||
|
|
||||||
|
let index = match self.db.open_index(&uid) {
|
||||||
|
Some(index) => index,
|
||||||
|
None => {
|
||||||
|
index_has_been_created = true;
|
||||||
|
self.create_index(&uid)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match f(&index) {
|
||||||
|
Ok(r) => Ok(r),
|
||||||
|
Err(err) => {
|
||||||
|
if index_has_been_created {
|
||||||
|
let _ = self.db.delete_index(&uid);
|
||||||
|
}
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,37 +160,6 @@ struct UpdateDocumentsQuery {
|
|||||||
primary_key: Option<String>,
|
primary_key: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_index(data: &Data, uid: &str) -> Result<Index, ResponseError> {
|
|
||||||
if !uid
|
|
||||||
.chars()
|
|
||||||
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
|
||||||
{
|
|
||||||
return Err(Error::InvalidIndexUid.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let created_index = data.db.create_index(&uid).map_err(|e| match e {
|
|
||||||
meilisearch_core::Error::IndexAlreadyExists => e.into(),
|
|
||||||
_ => ResponseError::from(Error::create_index(e)),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
data.db.main_write::<_, _, ResponseError>(|mut writer| {
|
|
||||||
created_index.main.put_name(&mut writer, uid)?;
|
|
||||||
|
|
||||||
created_index
|
|
||||||
.main
|
|
||||||
.created_at(&writer)?
|
|
||||||
.ok_or(Error::internal("Impossible to read created at"))?;
|
|
||||||
|
|
||||||
created_index
|
|
||||||
.main
|
|
||||||
.updated_at(&writer)?
|
|
||||||
.ok_or(Error::internal("Impossible to read updated at"))?;
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(created_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_multiple_documents(
|
async fn update_multiple_documents(
|
||||||
data: web::Data<Data>,
|
data: web::Data<Data>,
|
||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
@ -198,12 +167,7 @@ async fn update_multiple_documents(
|
|||||||
body: web::Json<Vec<Document>>,
|
body: web::Json<Vec<Document>>,
|
||||||
is_partial: bool,
|
is_partial: bool,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let index = data
|
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||||
.db
|
|
||||||
.open_index(&path.index_uid)
|
|
||||||
.ok_or(Error::index_not_found(&path.index_uid))
|
|
||||||
.or(create_index(&data, &path.index_uid))?;
|
|
||||||
|
|
||||||
let reader = data.db.main_read_txn()?;
|
let reader = data.db.main_read_txn()?;
|
||||||
|
|
||||||
let mut schema = index
|
let mut schema = index
|
||||||
@ -235,9 +199,9 @@ async fn update_multiple_documents(
|
|||||||
document_addition.update_document(document);
|
document_addition.update_document(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| document_addition.finalize(w))?;
|
Ok(data.db.update_write(|w| document_addition.finalize(w))?)
|
||||||
|
})?;
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
return Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]
|
#[post("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]
|
||||||
|
@ -53,13 +53,12 @@ async fn update_all(
|
|||||||
path: web::Path<IndexParam>,
|
path: web::Path<IndexParam>,
|
||||||
body: web::Json<Settings>,
|
body: web::Json<Settings>,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let settings = body
|
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||||
.into_inner()
|
Ok(data.db.update_write::<_, _, ResponseError>(|writer| {
|
||||||
.to_update()
|
let settings = body.into_inner().to_update().map_err(Error::bad_request)?;
|
||||||
.map_err(Error::bad_request)?;
|
let update_id = index.settings_update(writer, settings)?;
|
||||||
|
Ok(update_id)
|
||||||
let update_id = data.db.update_write::<_, _, Error>(|writer| {
|
})?)
|
||||||
update_all_settings_txn(&data, settings, &path.index_uid, writer)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
@ -71,11 +70,7 @@ pub fn get_all_sync(data: &web::Data<Data>, reader: &MainReader, index_uid: &str
|
|||||||
.open_index(index_uid)
|
.open_index(index_uid)
|
||||||
.ok_or(Error::index_not_found(index_uid))?;
|
.ok_or(Error::index_not_found(index_uid))?;
|
||||||
|
|
||||||
let stop_words: BTreeSet<String> = index
|
let stop_words: BTreeSet<String> = index.main.stop_words(&reader)?.into_iter().collect();
|
||||||
.main
|
|
||||||
.stop_words(reader)?
|
|
||||||
.into_iter()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let synonyms_list = index.main.synonyms(reader)?;
|
let synonyms_list = index.main.synonyms(reader)?;
|
||||||
|
|
||||||
@ -94,22 +89,19 @@ pub fn get_all_sync(data: &web::Data<Data>, reader: &MainReader, index_uid: &str
|
|||||||
.map(|r| r.to_string())
|
.map(|r| r.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let schema = index.main.schema(&reader)?;
|
||||||
let schema = index.main.schema(reader)?;
|
|
||||||
|
|
||||||
let distinct_attribute = match (index.main.distinct_attribute(reader)?, &schema) {
|
let distinct_attribute = match (index.main.distinct_attribute(reader)?, &schema) {
|
||||||
(Some(id), Some(schema)) => schema.name(id).map(str::to_string),
|
(Some(id), Some(schema)) => schema.name(id).map(str::to_string),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let attributes_for_faceting = match (&schema, &index.main.attributes_for_faceting(reader)?) {
|
let attributes_for_faceting = match (&schema, &index.main.attributes_for_faceting(&reader)?) {
|
||||||
(Some(schema), Some(attrs)) => {
|
(Some(schema), Some(attrs)) => attrs
|
||||||
attrs
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&id| schema.name(id))
|
.filter_map(|&id| schema.name(id))
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
.collect()
|
.collect(),
|
||||||
}
|
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -159,7 +151,9 @@ async fn delete_all(
|
|||||||
attributes_for_faceting: UpdateState::Clear,
|
attributes_for_faceting: UpdateState::Clear,
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -209,7 +203,9 @@ async fn update_rules(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -232,7 +228,9 @@ async fn delete_rules(
|
|||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -280,7 +278,9 @@ async fn update_distinct(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -303,7 +303,9 @@ async fn delete_distinct(
|
|||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -322,8 +324,7 @@ async fn get_searchable(
|
|||||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||||
let reader = data.db.main_read_txn()?;
|
let reader = data.db.main_read_txn()?;
|
||||||
let schema = index.main.schema(&reader)?;
|
let schema = index.main.schema(&reader)?;
|
||||||
let searchable_attributes: Option<Vec<String>> =
|
let searchable_attributes: Option<Vec<String>> = schema.as_ref().map(get_indexed_attributes);
|
||||||
schema.as_ref().map(get_indexed_attributes);
|
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(searchable_attributes))
|
Ok(HttpResponse::Ok().json(searchable_attributes))
|
||||||
}
|
}
|
||||||
@ -349,7 +350,9 @@ async fn update_searchable(
|
|||||||
|
|
||||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -372,7 +375,9 @@ async fn delete_searchable(
|
|||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -418,7 +423,9 @@ async fn update_displayed(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -441,7 +448,9 @@ async fn delete_displayed(
|
|||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -459,20 +468,16 @@ async fn get_attributes_for_faceting(
|
|||||||
.open_index(&path.index_uid)
|
.open_index(&path.index_uid)
|
||||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||||
|
|
||||||
let attributes_for_faceting = data
|
let attributes_for_faceting = data.db.main_read::<_, _, ResponseError>(|reader| {
|
||||||
.db
|
|
||||||
.main_read::<_, _, ResponseError>(|reader| {
|
|
||||||
let schema = index.main.schema(reader)?;
|
let schema = index.main.schema(reader)?;
|
||||||
let attrs = index.main.attributes_for_faceting(reader)?;
|
let attrs = index.main.attributes_for_faceting(reader)?;
|
||||||
let attr_names = match (&schema, &attrs) {
|
let attr_names = match (&schema, &attrs) {
|
||||||
(Some(schema), Some(attrs)) => {
|
(Some(schema), Some(attrs)) => attrs
|
||||||
attrs
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&id| schema.name(id))
|
.filter_map(|&id| schema.name(id))
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
.collect()
|
.collect(),
|
||||||
}
|
_ => vec![],
|
||||||
_ => vec![]
|
|
||||||
};
|
};
|
||||||
Ok(attr_names)
|
Ok(attr_names)
|
||||||
})?;
|
})?;
|
||||||
@ -500,7 +505,9 @@ async fn update_attributes_for_faceting(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -523,7 +530,9 @@ async fn delete_attributes_for_faceting(
|
|||||||
..SettingsUpdate::default()
|
..SettingsUpdate::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
let update_id = data
|
||||||
|
.db
|
||||||
|
.update_write(|w| index.settings_update(w, settings))?;
|
||||||
|
|
||||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||||
}
|
}
|
||||||
@ -532,7 +541,8 @@ fn get_indexed_attributes(schema: &Schema) -> Vec<String> {
|
|||||||
if schema.is_indexed_all() {
|
if schema.is_indexed_all() {
|
||||||
["*"].iter().map(|s| s.to_string()).collect()
|
["*"].iter().map(|s| s.to_string()).collect()
|
||||||
} else {
|
} else {
|
||||||
schema.indexed_name()
|
schema
|
||||||
|
.indexed_name()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
@ -543,7 +553,8 @@ fn get_displayed_attributes(schema: &Schema) -> HashSet<String> {
|
|||||||
if schema.is_displayed_all() {
|
if schema.is_displayed_all() {
|
||||||
["*"].iter().map(|s| s.to_string()).collect()
|
["*"].iter().map(|s| s.to_string()).collect()
|
||||||
} else {
|
} else {
|
||||||
schema.displayed_name()
|
schema
|
||||||
|
.displayed_name()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.collect()
|
.collect()
|
||||||
|
Loading…
Reference in New Issue
Block a user