From d90926f59d65ca5b53d6209f2dcaf267c698973b Mon Sep 17 00:00:00 2001 From: Charlotte Vermandel Date: Tue, 15 Nov 2022 19:47:40 +0100 Subject: [PATCH 1/2] Add delete tasks for v0.30.0 --- src/client.rs | 38 +++++++++++++++++++++-- src/tasks.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/src/client.rs b/src/client.rs index 563bf103..a8c00964 100644 --- a/src/client.rs +++ b/src/client.rs @@ -4,7 +4,7 @@ use crate::{ key::{Key, KeyBuilder, KeyUpdater, KeysQuery, KeysResults}, request::*, task_info::TaskInfo, - tasks::{Task, TasksCancelQuery, TasksResults, TasksSearchQuery}, + tasks::{Task, TasksCancelQuery, TasksDeleteQuery, TasksResults, TasksSearchQuery}, utils::async_sleep, }; use serde::Deserialize; @@ -788,7 +788,7 @@ impl Client { /// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY); /// /// let mut query = tasks::TasksCancelQuery::new(&client); - /// query.with_index_uids(["get_tasks_with"]); + /// query.with_index_uids(["movies"]); /// /// let res = client.cancel_tasks_with(&query).await.unwrap(); /// # }); @@ -811,6 +811,40 @@ impl Client { Ok(tasks) } + /// Delete tasks with filters [TasksDeleteQuery] + /// + /// # Example + /// + /// ``` + /// # use meilisearch_sdk::*; + /// # + /// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700"); + /// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey"); + /// # + /// # futures::executor::block_on(async move { + /// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY); + /// + /// let mut query = tasks::TasksDeleteQuery::new(&client); + /// query.with_index_uids(["movies"]); + /// + /// let res = client.delete_tasks_with(&query).await.unwrap(); + /// # }); + /// ``` + pub async fn delete_tasks_with( + &self, + filters: &TasksDeleteQuery<'_>, + ) -> Result { + let tasks = request::<&TasksDeleteQuery, (), TaskInfo>( + &format!("{}/tasks", self.host), + &self.api_key, + Method::Delete { query: filters }, + 200, + ) + .await?; + + Ok(tasks) + } + /// Get all tasks from the server. /// /// # Example diff --git a/src/tasks.rs b/src/tasks.rs index a1670381..23672117 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -33,7 +33,10 @@ pub enum TaskType { details: Option, }, TaskCancelation { - details: Option, + details: Option, + }, + TaskDeletion { + details: Option, }, } @@ -87,7 +90,15 @@ pub struct DumpCreation { pub struct TaskCancelation { pub matched_tasks: usize, pub canceled_tasks: usize, - pub original_filters: usize, + pub original_filters: String, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TaskDeletion { + pub matched_tasks: usize, + pub deleted_tasks: usize, + pub original_filters: String, } #[derive(Deserialize, Debug, Clone)] @@ -424,8 +435,12 @@ pub struct TasksPaginationFilters { #[derive(Debug, Serialize, Clone)] pub struct TasksCancelFilters {} +#[derive(Debug, Serialize, Clone)] +pub struct TasksDeleteFilters {} + pub type TasksSearchQuery<'a> = TasksQuery<'a, TasksPaginationFilters>; pub type TasksCancelQuery<'a> = TasksQuery<'a, TasksCancelFilters>; +pub type TasksDeleteQuery<'a> = TasksQuery<'a, TasksDeleteFilters>; #[derive(Debug, Serialize, Clone)] #[serde(rename_all = "camelCase")] @@ -582,6 +597,29 @@ impl<'a> TasksQuery<'a, TasksCancelFilters> { } } +impl<'a> TasksQuery<'a, TasksDeleteFilters> { + pub fn new(client: &'a Client) -> TasksQuery<'a, TasksDeleteFilters> { + TasksQuery { + client, + index_uids: None, + statuses: None, + task_types: None, + uids: None, + before_enqueued_at: None, + after_enqueued_at: None, + before_started_at: None, + after_started_at: None, + before_finished_at: None, + after_finished_at: None, + pagination: TasksDeleteFilters {}, + } + } + + pub async fn execute(&'a self) -> Result { + self.client.delete_tasks_with(self).await + } +} + impl<'a> TasksQuery<'a, TasksPaginationFilters> { pub fn new(client: &'a Client) -> TasksQuery<'a, TasksPaginationFilters> { TasksQuery { @@ -973,4 +1011,46 @@ mod test { mock_res.assert(); Ok(()) } + + #[meilisearch_test] + async fn test_delete_tasks_with_params() -> Result<(), Error> { + let mock_server_url = &mockito::server_url(); + let client = Client::new(mock_server_url, "masterKey"); + let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1"; + + let mock_res = mock("DELETE", path).with_status(200).create(); + + let mut query = TasksDeleteQuery::new(&client); + query + .with_index_uids(["movies", "test"]) + .with_statuses(["equeued"]) + .with_types(["documentDeletion"]) + .with_uids([&1]); + + let _ = client.delete_tasks_with(&query).await; + + mock_res.assert(); + Ok(()) + } + + #[meilisearch_test] + async fn test_delete_tasks_with_params_execute() -> Result<(), Error> { + let mock_server_url = &mockito::server_url(); + let client = Client::new(mock_server_url, "masterKey"); + let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1"; + + let mock_res = mock("DELETE", path).with_status(200).create(); + + let mut query = TasksDeleteQuery::new(&client); + let _ = query + .with_index_uids(["movies", "test"]) + .with_statuses(["equeued"]) + .with_types(["documentDeletion"]) + .with_uids([&1]) + .execute() + .await; + + mock_res.assert(); + Ok(()) + } } From 5d834cb04251be8914db1447659ec67ea8564e5b Mon Sep 17 00:00:00 2001 From: cvermand <33010418+bidoubiwa@users.noreply.github.com> Date: Thu, 17 Nov 2022 13:53:27 +0100 Subject: [PATCH 2/2] Add swap indexes for v0.30.0 (#382) * Add swap indexes for v0.30.0 * Implement swap indexes * Add indexSwap detail * Use tuples as type for the indexes field * Add tests on index swap * Create better documentation for indexes swap * Fix clippy errors * Fix missing bracket * Fix swap doc test * Make doc more clear --- src/client.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++- src/tasks.rs | 11 ++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/client.rs b/src/client.rs index 634df98f..3ef61753 100644 --- a/src/client.rs +++ b/src/client.rs @@ -7,7 +7,7 @@ use crate::{ tasks::{Task, TasksCancelQuery, TasksDeleteQuery, TasksResults, TasksSearchQuery}, utils::async_sleep, }; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use std::{collections::HashMap, time::Duration}; use time::OffsetDateTime; @@ -19,6 +19,11 @@ pub struct Client { pub(crate) api_key: String, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SwapIndexes { + pub indexes: (String, String), +} + impl Client { /// Create a client using the specified server. /// Don't put a '/' at the end of the host. @@ -329,6 +334,56 @@ impl Client { self.list_all_indexes_raw_with(indexes_query).await } + /// Swaps a list of two [Index]'es. + /// + /// # Example + /// + /// ``` + /// # use meilisearch_sdk::{client::*, indexes::*}; + /// # + /// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700"); + /// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey"); + /// # + /// # futures::executor::block_on(async move { + /// // Create the client + /// let client = Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY); + /// + /// let task_index_1 = client.create_index("swap_index_1", None).await.unwrap(); + /// let task_index_2 = client.create_index("swap_index_2", None).await.unwrap(); + /// + /// // Wait for the task to complete + /// task_index_2.wait_for_completion(&client, None, None).await.unwrap(); + /// + /// let task = client + /// .swap_indexes([&SwapIndexes { + /// indexes: ( + /// "swap_index_1".to_string(), + /// "swap_index_2".to_string(), + /// ), + /// }]) + /// .await + /// .unwrap(); + /// + /// # client.index("swap_index_1").delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap(); + /// # client.index("swap_index_2").delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap(); + /// # }); + /// ``` + pub async fn swap_indexes( + &self, + indexes: impl IntoIterator, + ) -> Result { + request::<(), Vec<&SwapIndexes>, TaskInfo>( + &format!("{}/swap-indexes", self.host), + &self.api_key, + Method::Post { + query: (), + body: indexes.into_iter().collect(), + }, + 202, + ) + .await + } + /// Get stats of all indexes. /// /// # Example @@ -961,6 +1016,59 @@ mod tests { use std::mem; use time::OffsetDateTime; + #[derive(Debug, Serialize, Deserialize, PartialEq)] + struct Document { + id: String, + } + + #[meilisearch_test] + async fn test_swapping_two_indexes(client: Client) { + let index_1 = client.index("test_swapping_two_indexes_1"); + let index_2 = client.index("test_swapping_two_indexes_2"); + + let t0 = index_1 + .add_documents( + &[Document { + id: "1".to_string(), + }], + None, + ) + .await + .unwrap(); + + index_2 + .add_documents( + &[Document { + id: "2".to_string(), + }], + None, + ) + .await + .unwrap(); + + t0.wait_for_completion(&client, None, None).await.unwrap(); + + let task = client + .swap_indexes([&SwapIndexes { + indexes: ( + "test_swapping_two_indexes_1".to_string(), + "test_swapping_two_indexes_2".to_string(), + ), + }]) + .await + .unwrap(); + task.wait_for_completion(&client, None, None).await.unwrap(); + + let document = index_1.get_document("2").await.unwrap(); + + assert_eq!( + Document { + id: "2".to_string() + }, + document + ); + } + #[meilisearch_test] async fn test_methods_has_qualified_version_as_header() { let mock_server_url = &mockito::server_url(); diff --git a/src/tasks.rs b/src/tasks.rs index b39bfe92..6be7f2ec 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -4,7 +4,7 @@ use time::OffsetDateTime; use crate::{ client::Client, errors::Error, errors::MeilisearchError, indexes::Index, settings::Settings, - task_info::TaskInfo, + task_info::TaskInfo, SwapIndexes, }; #[derive(Debug, Clone, Deserialize)] @@ -32,6 +32,9 @@ pub enum TaskType { DumpCreation { details: Option, }, + IndexSwap { + details: Option, + }, TaskCancelation { details: Option, }, @@ -92,6 +95,12 @@ pub struct DumpCreation { pub dump_uid: Option, } +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct IndexSwap { + pub swaps: Vec, +} + #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TaskCancelation {