mod index_store; mod update_store; pub use index_store::IndexStore; pub use update_store::UpdateStore; use std::num::NonZeroUsize; use std::ops::Deref; use std::collections::HashMap; use anyhow::Result; use milli::update::{IndexDocumentsMethod, UpdateFormat}; use milli::update_store::{Processed, Processing, Failed, Pending, Aborted}; use serde::{Serialize, Deserialize, de::Deserializer}; pub type UpdateStatusResponse = UpdateStatus; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type")] pub enum UpdateMeta { DocumentsAddition { method: IndexDocumentsMethod, format: UpdateFormat }, ClearDocuments, Settings(Settings), Facets(Facets), } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(deny_unknown_fields)] #[serde(rename_all = "camelCase")] pub struct Facets { pub level_group_size: Option, pub min_level_size: Option, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type")] pub enum UpdateStatus { Pending { update_id: u64, meta: Pending }, Progressing { update_id: u64, meta: P }, Processed { update_id: u64, meta: Processed }, Aborted { update_id: u64, meta: Aborted }, } fn deserialize_some<'de, T, D>(deserializer: D) -> Result, D::Error> where T: Deserialize<'de>, D: Deserializer<'de> { Deserialize::deserialize(deserializer).map(Some) } #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(deny_unknown_fields)] #[serde(rename_all = "camelCase")] pub struct Settings { #[serde( default, deserialize_with = "deserialize_some", skip_serializing_if = "Option::is_none", )] pub displayed_attributes: Option>>, #[serde( default, deserialize_with = "deserialize_some", skip_serializing_if = "Option::is_none", )] pub searchable_attributes: Option>>, #[serde(default)] pub faceted_attributes: Option>>, #[serde( default, deserialize_with = "deserialize_some", skip_serializing_if = "Option::is_none", )] pub criteria: Option>>, } impl Settings { pub fn cleared() -> Self { Self { displayed_attributes: Some(None), searchable_attributes: Some(None), faceted_attributes: Some(None), criteria: Some(None), } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum UpdateResult { //DocumentsAddition(DocumentAdditionResult), Other, } /// The `IndexController` is in charge of the access to the underlying indices. It splits the logic /// for read access which is provided, and write access which must be provided. This allows the /// implementer to define the behaviour of write accesses to the indices, and abstract the /// scheduling of the updates. The implementer must be able to provide an instance of `IndexStore` pub trait IndexController: Deref { /* * Write operations * * Logic for the write operation need to be provided by the implementer, since they can be made * asynchronous thanks to an update_store for example. * * */ /// Perform document addition on the database. If the provided index does not exist, it will be /// created when the addition is applied to the index. fn add_documents>( &self, index: S, method: IndexDocumentsMethod, format: UpdateFormat, data: &[u8], ) -> anyhow::Result; /// Updates an index settings. If the index does not exist, it will be created when the update /// is applied to the index. fn update_settings>(&self, index_uid: S, settings: Settings) -> anyhow::Result; /// Create an index with the given `index_uid`. fn create_index>(&self, index_uid: S) -> Result<()>; /// Delete index with the given `index_uid`, attempting to close it beforehand. fn delete_index>(&self, index_uid: S) -> Result<()>; /// Swap two indexes, concretely, it simply swaps the index the names point to. fn swap_indices, S2: AsRef>(&self, index1_uid: S1, index2_uid: S2) -> Result<()>; /// Apply an update to the given index. This method can be called when an update is ready to be /// processed fn handle_update>( &self, _index: S, _update_id: u64, _meta: Processing, _content: &[u8] ) -> Result, Failed> { todo!() } }