MeiliSearch/meilisearch-http/src/data/updates.rs

116 lines
4.0 KiB
Rust
Raw Normal View History

2020-12-29 11:11:06 +01:00
use std::ops::Deref;
use async_compression::tokio_02::write::GzipEncoder;
use futures_util::stream::StreamExt;
2021-02-18 20:28:10 +01:00
use milli::update::{IndexDocumentsMethod, UpdateFormat};
2020-12-29 11:11:06 +01:00
use tokio::io::AsyncWriteExt;
2021-02-01 19:51:47 +01:00
use crate::index_controller::UpdateStatus;
2021-02-18 20:28:10 +01:00
use crate::index_controller::{IndexController, Settings, IndexSettings, IndexMetadata};
use super::Data;
2020-12-29 11:11:06 +01:00
impl Data {
2021-02-01 19:51:47 +01:00
pub async fn add_documents<B, E>(
2020-12-29 11:11:06 +01:00
&self,
2021-02-01 19:51:47 +01:00
index: impl AsRef<str> + Send + Sync + 'static,
2020-12-29 11:11:06 +01:00
method: IndexDocumentsMethod,
format: UpdateFormat,
mut stream: impl futures::Stream<Item=Result<B, E>> + Unpin,
2021-02-13 12:22:59 +01:00
primary_key: Option<String>,
2021-02-01 19:51:47 +01:00
) -> anyhow::Result<UpdateStatus>
2020-12-29 11:11:06 +01:00
where
B: Deref<Target = [u8]>,
E: std::error::Error + Send + Sync + 'static,
{
let file = tokio::task::spawn_blocking(tempfile::tempfile).await?;
let file = tokio::fs::File::from_std(file?);
let mut encoder = GzipEncoder::new(file);
2021-02-04 13:21:15 +01:00
let mut empty_update = true;
2020-12-29 11:11:06 +01:00
while let Some(result) = stream.next().await {
2021-02-04 13:21:15 +01:00
empty_update = false;
2020-12-29 11:11:06 +01:00
let bytes = &*result?;
encoder.write_all(&bytes[..]).await?;
}
encoder.shutdown().await?;
let mut file = encoder.into_inner();
file.sync_all().await?;
let file = file.into_std().await;
2021-02-04 13:21:15 +01:00
2021-01-28 14:12:34 +01:00
let index_controller = self.index_controller.clone();
2021-02-04 13:21:15 +01:00
let update = tokio::task::spawn_blocking(move ||{
let mmap;
let bytes = if empty_update {
&[][..]
} else {
mmap = unsafe { memmap::Mmap::map(&file)? };
&mmap
};
2021-02-13 12:22:59 +01:00
index_controller.add_documents(index, method, format, &bytes, primary_key)
2021-02-04 13:21:15 +01:00
}).await??;
2020-12-29 11:11:06 +01:00
Ok(update.into())
}
2021-02-01 19:51:47 +01:00
pub async fn update_settings(
2021-01-01 16:59:49 +01:00
&self,
2021-02-01 19:51:47 +01:00
index: impl AsRef<str> + Send + Sync + 'static,
2021-01-01 16:59:49 +01:00
settings: Settings
2021-02-01 19:51:47 +01:00
) -> anyhow::Result<UpdateStatus> {
let index_controller = self.index_controller.clone();
let update = tokio::task::spawn_blocking(move || index_controller.update_settings(index, settings)).await??;
2021-01-01 16:59:49 +01:00
Ok(update.into())
}
2020-12-29 11:11:06 +01:00
2021-02-11 12:03:00 +01:00
pub async fn clear_documents(
&self,
2021-02-13 10:44:20 +01:00
index: impl AsRef<str> + Sync + Send + 'static,
2021-02-11 12:03:00 +01:00
) -> anyhow::Result<UpdateStatus> {
let index_controller = self.index_controller.clone();
let update = tokio::task::spawn_blocking(move || index_controller.clear_documents(index)).await??;
Ok(update.into())
}
2021-02-12 17:39:14 +01:00
pub async fn delete_documents(
&self,
2021-02-13 10:44:20 +01:00
index: impl AsRef<str> + Sync + Send + 'static,
2021-02-12 17:39:14 +01:00
document_ids: Vec<String>,
) -> anyhow::Result<UpdateStatus> {
let index_controller = self.index_controller.clone();
let update = tokio::task::spawn_blocking(move || index_controller.delete_documents(index, document_ids)).await??;
Ok(update.into())
}
2021-02-15 10:53:21 +01:00
pub async fn delete_index(
&self,
index: impl AsRef<str> + Send + Sync + 'static,
) -> anyhow::Result<()> {
let index_controller = self.index_controller.clone();
tokio::task::spawn_blocking(move || { index_controller.delete_index(index) }).await??;
Ok(())
}
2021-01-28 17:20:51 +01:00
#[inline]
2021-02-01 19:51:47 +01:00
pub fn get_update_status(&self, index: impl AsRef<str>, uid: u64) -> anyhow::Result<Option<UpdateStatus>> {
2021-01-28 17:20:51 +01:00
self.index_controller.update_status(index, uid)
}
2020-12-30 19:17:13 +01:00
2021-02-01 19:51:47 +01:00
pub fn get_updates_status(&self, index: impl AsRef<str>) -> anyhow::Result<Vec<UpdateStatus>> {
2021-01-28 18:32:24 +01:00
self.index_controller.all_update_status(index)
}
pub fn update_index(
&self,
name: impl AsRef<str>,
primary_key: Option<impl AsRef<str>>,
new_name: Option<impl AsRef<str>>
) -> anyhow::Result<IndexMetadata> {
let settings = IndexSettings {
name: new_name.map(|s| s.as_ref().to_string()),
primary_key: primary_key.map(|s| s.as_ref().to_string()),
};
self.index_controller.update_index(name, settings)
}
2020-12-29 11:11:06 +01:00
}