Skip to content

Add tasks filters for v0.30.0 #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Nov 15, 2022
6 changes: 3 additions & 3 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ get_all_tasks_1: |-
.unwrap();
get_all_tasks_filtering_1: |-
let mut query = TasksQuery::new(&client)
.with_index_uid(["movies"])
.with_index_uids(["movies"])
.execute()
.await
.unwrap();
get_all_tasks_filtering_2: |-
let mut query = TasksQuery::new(&client)
.with_status(["succeeded", "failed"])
.with_type(["documentAdditionOrUpdate"])
.with_statuses(["succeeded", "failed"])
.with_types(["documentAdditionOrUpdate"])
.execute()
.await
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.29.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.29.0).
This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0).

## ⚙️ Contributing

Expand Down
2 changes: 1 addition & 1 deletion README.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ WARNING: `meilisearch-sdk` will panic if no Window is available (ex: Web extensi

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.29.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.29.0).
This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0).

## ⚙️ Contributing

Expand Down
6 changes: 3 additions & 3 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ impl Client {
/// # let client = client::Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
///
/// let mut query = tasks::TasksQuery::new(&client);
/// query.with_index_uid(["get_tasks_with"]);
/// query.with_index_uids(["get_tasks_with"]);
/// let tasks = client.get_tasks_with(&query).await.unwrap();
/// # });
/// ```
Expand Down Expand Up @@ -930,15 +930,15 @@ mod tests {
#[meilisearch_test]
async fn test_get_tasks(client: Client) {
let tasks = client.get_tasks().await.unwrap();
assert!(tasks.results.len() >= 2);
assert!(tasks.limit == 20);
}

#[meilisearch_test]
async fn test_get_tasks_with_params(client: Client) {
let query = TasksQuery::new(&client);
let tasks = client.get_tasks_with(&query).await.unwrap();

assert!(tasks.results.len() >= 2);
assert!(tasks.limit == 20);
}

#[meilisearch_test]
Expand Down
6 changes: 6 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ pub enum ErrorCode {
InvalidApiKeyIndexes,
InvalidApiKeyExpiresAt,
ApiKeyNotFound,
InvalidTaskTypesFilter,
InvalidTaskStatusesFilter,
InvalidTaskCanceledByFilter,
InvalidTaskUidsFilter,
InvalidTaskDateFilter,
MissingTaskFilters,

/// That's unexpected. Please open a GitHub issue after ensuring you are
/// using the supported version of the Meilisearch server.
Expand Down
9 changes: 5 additions & 4 deletions src/indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@ impl Index {
///
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_URL, MEILISEARCH_API_KEY);
/// let movie_index = client.index("get_documents");
///
/// let movie_index = client.index("get_documents_with");
///
/// # movie_index.add_or_replace(&[Movie{name:String::from("Interstellar"), description:String::from("Interstellar chronicles the adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.")}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
///
Expand Down Expand Up @@ -902,7 +903,7 @@ impl Index {
/// ```
pub async fn get_tasks(&self) -> Result<TasksResults, Error> {
let mut query = TasksQuery::new(&self.client);
query.with_index_uid([self.uid.as_str()]);
query.with_index_uids([self.uid.as_str()]);

self.client.get_tasks_with(&query).await
}
Expand All @@ -923,7 +924,7 @@ impl Index {
/// # let index = client.create_index("get_tasks_with", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap().try_make_index(&client).unwrap();
///
/// let mut query = TasksQuery::new(&client);
/// query.with_index_uid(["none_existant"]);
/// query.with_index_uids(["none_existant"]);
/// let tasks = index.get_tasks_with(&query).await.unwrap();
///
/// assert!(tasks.results.len() > 0);
Expand All @@ -935,7 +936,7 @@ impl Index {
tasks_query: &TasksQuery<'_>,
) -> Result<TasksResults, Error> {
let mut query = tasks_query.clone();
query.with_index_uid([self.uid.as_str()]);
query.with_index_uids([self.uid.as_str()]);

self.client.get_tasks_with(&query).await
}
Expand Down
215 changes: 187 additions & 28 deletions src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,52 @@ pub struct TasksQuery<'a> {
pub client: &'a Client,
// Index uids array to only retrieve the tasks of the indexes.
#[serde(skip_serializing_if = "Option::is_none")]
pub index_uid: Option<Vec<&'a str>>,
pub index_uids: Option<Vec<&'a str>>,
// Statuses array to only retrieve the tasks with these statuses.
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<Vec<&'a str>>,
pub statuses: Option<Vec<&'a str>>,
// Types array to only retrieve the tasks with these [TaskType].
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
pub task_type: Option<Vec<&'a str>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "types")]
pub task_types: Option<Vec<&'a str>>,
// Uids of the tasks to retrieve
#[serde(skip_serializing_if = "Option::is_none")]
pub uids: Option<Vec<&'a u32>>,
// Date to retrieve all tasks that were enqueued before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_enqueued_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were enqueued after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_enqueued_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were started before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_started_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were started after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_started_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were finished before it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub before_finished_at: Option<OffsetDateTime>,
// Date to retrieve all tasks that were finished after it.
#[serde(
skip_serializing_if = "Option::is_none",
serialize_with = "time::serde::rfc3339::option::serialize"
)]
pub after_finished_at: Option<OffsetDateTime>,
// Maximum number of tasks to return
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
Expand All @@ -426,32 +465,88 @@ impl<'a> TasksQuery<'a> {
pub fn new(client: &'a Client) -> TasksQuery<'a> {
TasksQuery {
client,
index_uid: None,
status: None,
task_type: None,
index_uids: None,
statuses: None,
task_types: None,
limit: None,
from: 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,
}
}
pub fn with_index_uid<'b>(
pub fn with_index_uids<'b>(
&'b mut self,
index_uids: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.index_uids = Some(index_uids.into_iter().collect());
self
}
pub fn with_statuses<'b>(
&'b mut self,
statuses: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.statuses = Some(statuses.into_iter().collect());
self
}
pub fn with_types<'b>(
&'b mut self,
task_types: impl IntoIterator<Item = &'a str>,
) -> &'b mut TasksQuery<'a> {
self.task_types = Some(task_types.into_iter().collect());
self
}
pub fn with_uids<'b>(
&'b mut self,
uids: impl IntoIterator<Item = &'a u32>,
) -> &'b mut TasksQuery<'a> {
self.uids = Some(uids.into_iter().collect());
self
}
pub fn with_before_enqueued_at<'b>(
&'b mut self,
index_uid: impl IntoIterator<Item = &'a str>,
before_enqueued_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.index_uid = Some(index_uid.into_iter().collect());
self.before_enqueued_at = Some(*before_enqueued_at);
self
}
pub fn with_status<'b>(
pub fn with_after_enqueued_at<'b>(
&'b mut self,
status: impl IntoIterator<Item = &'a str>,
after_enqueued_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.status = Some(status.into_iter().collect());
self.after_enqueued_at = Some(*after_enqueued_at);
self
}
pub fn with_type<'b>(
pub fn with_before_started_at<'b>(
&'b mut self,
task_type: impl IntoIterator<Item = &'a str>,
before_started_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.task_type = Some(task_type.into_iter().collect());
self.before_started_at = Some(*before_started_at);
self
}
pub fn with_after_started_at<'b>(
&'b mut self,
after_started_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.after_started_at = Some(*after_started_at);
self
}
pub fn with_before_finished_at<'b>(
&'b mut self,
before_finished_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.before_finished_at = Some(*before_finished_at);
self
}
pub fn with_after_finished_at<'b>(
&'b mut self,
after_finished_at: &'a OffsetDateTime,
) -> &'b mut TasksQuery<'a> {
self.after_finished_at = Some(*after_finished_at);
self
}
pub fn with_limit<'b>(&'b mut self, limit: u32) -> &'b mut TasksQuery<'a> {
Expand Down Expand Up @@ -640,17 +735,81 @@ mod test {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path =
"/tasks?indexUid=movies,test&status=equeued&type=documentDeletion&limit=0&from=1";
"/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion&uids=1&limit=0&from=1";

let mock_res = mock("GET", path).with_status(200).create();

let mut query = TasksQuery::new(&client);
query
.with_index_uid(["movies", "test"])
.with_status(["equeued"])
.with_type(["documentDeletion"])
.with_index_uids(["movies", "test"])
.with_statuses(["equeued"])
.with_types(["documentDeletion"])
.with_from(1)
.with_limit(0);
.with_limit(0)
.with_uids([&1]);

let _ = client.get_tasks_with(&query).await;

mock_res.assert();
Ok(())
}

#[meilisearch_test]
async fn test_get_tasks_with_date_params() -> Result<(), Error> {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path = "/tasks?\
beforeEnqueuedAt=2022-02-03T13%3A02%3A38.369634Z\
&afterEnqueuedAt=2023-02-03T13%3A02%3A38.369634Z\
&beforeStartedAt=2024-02-03T13%3A02%3A38.369634Z\
&afterStartedAt=2025-02-03T13%3A02%3A38.369634Z\
&beforeFinishedAt=2026-02-03T13%3A02%3A38.369634Z\
&afterFinishedAt=2027-02-03T13%3A02%3A38.369634Z";

let mock_res = mock("GET", path).with_status(200).create();

let before_enqueued_at = OffsetDateTime::parse(
"2022-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();
let after_enqueued_at = OffsetDateTime::parse(
"2023-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();
let before_started_at = OffsetDateTime::parse(
"2024-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let after_started_at = OffsetDateTime::parse(
"2025-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let before_finished_at = OffsetDateTime::parse(
"2026-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let after_finished_at = OffsetDateTime::parse(
"2027-02-03T13:02:38.369634Z",
&::time::format_description::well_known::Rfc3339,
)
.unwrap();

let mut query = TasksQuery::new(&client);
query
.with_before_enqueued_at(&before_enqueued_at)
.with_after_enqueued_at(&after_enqueued_at)
.with_before_started_at(&before_started_at)
.with_after_started_at(&after_started_at)
.with_before_finished_at(&before_finished_at)
.with_after_finished_at(&after_finished_at);

let _ = client.get_tasks_with(&query).await;

Expand All @@ -662,15 +821,15 @@ mod test {
async fn test_get_tasks_on_struct_with_params() -> Result<(), Error> {
let mock_server_url = &mockito::server_url();
let client = Client::new(mock_server_url, "masterKey");
let path = "/tasks?indexUid=movies,test&status=equeued&type=documentDeletion";
let path = "/tasks?indexUids=movies,test&statuses=equeued&types=documentDeletion";

let mock_res = mock("GET", path).with_status(200).create();

let mut query = TasksQuery::new(&client);
let _ = query
.with_index_uid(["movies", "test"])
.with_status(["equeued"])
.with_type(["documentDeletion"])
.with_index_uids(["movies", "test"])
.with_statuses(["equeued"])
.with_types(["documentDeletion"])
.execute()
.await;

Expand All @@ -680,9 +839,9 @@ mod test {
}

#[meilisearch_test]
async fn test_get_tasks_with_none_existant_index_uid(client: Client) -> Result<(), Error> {
async fn test_get_tasks_with_none_existant_index_uids(client: Client) -> Result<(), Error> {
let mut query = TasksQuery::new(&client);
query.with_index_uid(["no_name"]);
query.with_index_uids(["no_name"]);
let tasks = client.get_tasks_with(&query).await.unwrap();

assert_eq!(tasks.results.len(), 0);
Expand All @@ -692,7 +851,7 @@ mod test {
#[meilisearch_test]
async fn test_get_tasks_with_execute(client: Client) -> Result<(), Error> {
let tasks = TasksQuery::new(&client)
.with_index_uid(["no_name"])
.with_index_uids(["no_name"])
.execute()
.await
.unwrap();
Expand Down