Skip to content

Commit 54ffa60

Browse files
authored
Add delete tasks for v0.30.0 (#381)
* Add delete tasks for v0.30.0 * 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
1 parent a17b669 commit 54ffa60

File tree

2 files changed

+235
-4
lines changed

2 files changed

+235
-4
lines changed

src/client.rs

Lines changed: 145 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use crate::{
44
key::{Key, KeyBuilder, KeyUpdater, KeysQuery, KeysResults},
55
request::*,
66
task_info::TaskInfo,
7-
tasks::{Task, TasksCancelQuery, TasksResults, TasksSearchQuery},
7+
tasks::{Task, TasksCancelQuery, TasksDeleteQuery, TasksResults, TasksSearchQuery},
88
utils::async_sleep,
99
};
10-
use serde::Deserialize;
10+
use serde::{Deserialize, Serialize};
1111
use serde_json::{json, Value};
1212
use std::{collections::HashMap, time::Duration};
1313
use time::OffsetDateTime;
@@ -19,6 +19,11 @@ pub struct Client {
1919
pub(crate) api_key: String,
2020
}
2121

22+
#[derive(Debug, Clone, Serialize, Deserialize)]
23+
pub struct SwapIndexes {
24+
pub indexes: (String, String),
25+
}
26+
2227
impl Client {
2328
/// Create a client using the specified server.
2429
/// Don't put a '/' at the end of the host.
@@ -329,6 +334,56 @@ impl Client {
329334
self.list_all_indexes_raw_with(indexes_query).await
330335
}
331336

337+
/// Swaps a list of two [Index]'es.
338+
///
339+
/// # Example
340+
///
341+
/// ```
342+
/// # use meilisearch_sdk::{client::*, indexes::*};
343+
/// #
344+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
345+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
346+
/// #
347+
/// # futures::executor::block_on(async move {
348+
/// // Create the client
349+
/// let client = Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
350+
///
351+
/// let task_index_1 = client.create_index("swap_index_1", None).await.unwrap();
352+
/// let task_index_2 = client.create_index("swap_index_2", None).await.unwrap();
353+
///
354+
/// // Wait for the task to complete
355+
/// task_index_2.wait_for_completion(&client, None, None).await.unwrap();
356+
///
357+
/// let task = client
358+
/// .swap_indexes([&SwapIndexes {
359+
/// indexes: (
360+
/// "swap_index_1".to_string(),
361+
/// "swap_index_2".to_string(),
362+
/// ),
363+
/// }])
364+
/// .await
365+
/// .unwrap();
366+
///
367+
/// # client.index("swap_index_1").delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
368+
/// # client.index("swap_index_2").delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
369+
/// # });
370+
/// ```
371+
pub async fn swap_indexes(
372+
&self,
373+
indexes: impl IntoIterator<Item = &SwapIndexes>,
374+
) -> Result<TaskInfo, Error> {
375+
request::<(), Vec<&SwapIndexes>, TaskInfo>(
376+
&format!("{}/swap-indexes", self.host),
377+
&self.api_key,
378+
Method::Post {
379+
query: (),
380+
body: indexes.into_iter().collect(),
381+
},
382+
202,
383+
)
384+
.await
385+
}
386+
332387
/// Get stats of all indexes.
333388
///
334389
/// # Example
@@ -788,7 +843,7 @@ impl Client {
788843
/// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
789844
///
790845
/// let mut query = tasks::TasksCancelQuery::new(&client);
791-
/// query.with_index_uids(["get_tasks_with"]);
846+
/// query.with_index_uids(["movies"]);
792847
///
793848
/// let res = client.cancel_tasks_with(&query).await.unwrap();
794849
/// # });
@@ -811,6 +866,40 @@ impl Client {
811866
Ok(tasks)
812867
}
813868

869+
/// Delete tasks with filters [TasksDeleteQuery]
870+
///
871+
/// # Example
872+
///
873+
/// ```
874+
/// # use meilisearch_sdk::*;
875+
/// #
876+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
877+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
878+
/// #
879+
/// # futures::executor::block_on(async move {
880+
/// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
881+
///
882+
/// let mut query = tasks::TasksDeleteQuery::new(&client);
883+
/// query.with_index_uids(["movies"]);
884+
///
885+
/// let res = client.delete_tasks_with(&query).await.unwrap();
886+
/// # });
887+
/// ```
888+
pub async fn delete_tasks_with(
889+
&self,
890+
filters: &TasksDeleteQuery<'_>,
891+
) -> Result<TaskInfo, Error> {
892+
let tasks = request::<&TasksDeleteQuery, (), TaskInfo>(
893+
&format!("{}/tasks", self.host),
894+
&self.api_key,
895+
Method::Delete { query: filters },
896+
200,
897+
)
898+
.await?;
899+
900+
Ok(tasks)
901+
}
902+
814903
/// Get all tasks from the server.
815904
///
816905
/// # Example
@@ -927,6 +1016,59 @@ mod tests {
9271016
use std::mem;
9281017
use time::OffsetDateTime;
9291018

1019+
#[derive(Debug, Serialize, Deserialize, PartialEq)]
1020+
struct Document {
1021+
id: String,
1022+
}
1023+
1024+
#[meilisearch_test]
1025+
async fn test_swapping_two_indexes(client: Client) {
1026+
let index_1 = client.index("test_swapping_two_indexes_1");
1027+
let index_2 = client.index("test_swapping_two_indexes_2");
1028+
1029+
let t0 = index_1
1030+
.add_documents(
1031+
&[Document {
1032+
id: "1".to_string(),
1033+
}],
1034+
None,
1035+
)
1036+
.await
1037+
.unwrap();
1038+
1039+
index_2
1040+
.add_documents(
1041+
&[Document {
1042+
id: "2".to_string(),
1043+
}],
1044+
None,
1045+
)
1046+
.await
1047+
.unwrap();
1048+
1049+
t0.wait_for_completion(&client, None, None).await.unwrap();
1050+
1051+
let task = client
1052+
.swap_indexes([&SwapIndexes {
1053+
indexes: (
1054+
"test_swapping_two_indexes_1".to_string(),
1055+
"test_swapping_two_indexes_2".to_string(),
1056+
),
1057+
}])
1058+
.await
1059+
.unwrap();
1060+
task.wait_for_completion(&client, None, None).await.unwrap();
1061+
1062+
let document = index_1.get_document("2").await.unwrap();
1063+
1064+
assert_eq!(
1065+
Document {
1066+
id: "2".to_string()
1067+
},
1068+
document
1069+
);
1070+
}
1071+
9301072
#[meilisearch_test]
9311073
async fn test_methods_has_qualified_version_as_header() {
9321074
let mock_server_url = &mockito::server_url();

src/tasks.rs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use time::OffsetDateTime;
44

55
use crate::{
66
client::Client, errors::Error, errors::MeilisearchError, indexes::Index, settings::Settings,
7-
task_info::TaskInfo,
7+
task_info::TaskInfo, SwapIndexes,
88
};
99

1010
#[derive(Debug, Clone, Deserialize)]
@@ -32,9 +32,15 @@ pub enum TaskType {
3232
DumpCreation {
3333
details: Option<DumpCreation>,
3434
},
35+
IndexSwap {
36+
details: Option<IndexSwap>,
37+
},
3538
TaskCancelation {
3639
details: Option<TaskCancelation>,
3740
},
41+
TaskDeletion {
42+
details: Option<TaskDeletion>,
43+
},
3844
SnapshotCreation {
3945
details: Option<SnapshotCreation>,
4046
},
@@ -89,6 +95,12 @@ pub struct DumpCreation {
8995
pub dump_uid: Option<String>,
9096
}
9197

98+
#[derive(Debug, Clone, Deserialize)]
99+
#[serde(rename_all = "camelCase")]
100+
pub struct IndexSwap {
101+
pub swaps: Vec<SwapIndexes>,
102+
}
103+
92104
#[derive(Debug, Clone, Deserialize)]
93105
#[serde(rename_all = "camelCase")]
94106
pub struct TaskCancelation {
@@ -97,6 +109,14 @@ pub struct TaskCancelation {
97109
pub original_filters: String,
98110
}
99111

112+
#[derive(Debug, Clone, Deserialize)]
113+
#[serde(rename_all = "camelCase")]
114+
pub struct TaskDeletion {
115+
pub matched_tasks: usize,
116+
pub deleted_tasks: usize,
117+
pub original_filters: String,
118+
}
119+
100120
#[derive(Deserialize, Debug, Clone)]
101121
#[serde(rename_all = "camelCase")]
102122
pub struct FailedTask {
@@ -433,8 +453,12 @@ pub struct TasksPaginationFilters {
433453
#[derive(Debug, Serialize, Clone)]
434454
pub struct TasksCancelFilters {}
435455

456+
#[derive(Debug, Serialize, Clone)]
457+
pub struct TasksDeleteFilters {}
458+
436459
pub type TasksSearchQuery<'a> = TasksQuery<'a, TasksPaginationFilters>;
437460
pub type TasksCancelQuery<'a> = TasksQuery<'a, TasksCancelFilters>;
461+
pub type TasksDeleteQuery<'a> = TasksQuery<'a, TasksDeleteFilters>;
438462

439463
#[derive(Debug, Serialize, Clone)]
440464
#[serde(rename_all = "camelCase")]
@@ -591,6 +615,29 @@ impl<'a> TasksQuery<'a, TasksCancelFilters> {
591615
}
592616
}
593617

618+
impl<'a> TasksQuery<'a, TasksDeleteFilters> {
619+
pub fn new(client: &'a Client) -> TasksQuery<'a, TasksDeleteFilters> {
620+
TasksQuery {
621+
client,
622+
index_uids: None,
623+
statuses: None,
624+
task_types: None,
625+
uids: None,
626+
before_enqueued_at: None,
627+
after_enqueued_at: None,
628+
before_started_at: None,
629+
after_started_at: None,
630+
before_finished_at: None,
631+
after_finished_at: None,
632+
pagination: TasksDeleteFilters {},
633+
}
634+
}
635+
636+
pub async fn execute(&'a self) -> Result<TaskInfo, Error> {
637+
self.client.delete_tasks_with(self).await
638+
}
639+
}
640+
594641
impl<'a> TasksQuery<'a, TasksPaginationFilters> {
595642
pub fn new(client: &'a Client) -> TasksQuery<'a, TasksPaginationFilters> {
596643
TasksQuery {
@@ -982,4 +1029,46 @@ mod test {
9821029
mock_res.assert();
9831030
Ok(())
9841031
}
1032+
1033+
#[meilisearch_test]
1034+
async fn test_delete_tasks_with_params() -> Result<(), Error> {
1035+
let mock_server_url = &mockito::server_url();
1036+
let client = Client::new(mock_server_url, "masterKey");
1037+
let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1";
1038+
1039+
let mock_res = mock("DELETE", path).with_status(200).create();
1040+
1041+
let mut query = TasksDeleteQuery::new(&client);
1042+
query
1043+
.with_index_uids(["movies", "test"])
1044+
.with_statuses(["equeued"])
1045+
.with_types(["documentDeletion"])
1046+
.with_uids([&1]);
1047+
1048+
let _ = client.delete_tasks_with(&query).await;
1049+
1050+
mock_res.assert();
1051+
Ok(())
1052+
}
1053+
1054+
#[meilisearch_test]
1055+
async fn test_delete_tasks_with_params_execute() -> Result<(), Error> {
1056+
let mock_server_url = &mockito::server_url();
1057+
let client = Client::new(mock_server_url, "masterKey");
1058+
let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1";
1059+
1060+
let mock_res = mock("DELETE", path).with_status(200).create();
1061+
1062+
let mut query = TasksDeleteQuery::new(&client);
1063+
let _ = query
1064+
.with_index_uids(["movies", "test"])
1065+
.with_statuses(["equeued"])
1066+
.with_types(["documentDeletion"])
1067+
.with_uids([&1])
1068+
.execute()
1069+
.await;
1070+
1071+
mock_res.assert();
1072+
Ok(())
1073+
}
9851074
}

0 commit comments

Comments
 (0)