Skip to content

Commit b0efa85

Browse files
bors[bot]Mubelotix
andauthored
Merge #113
113: Implement dumps r=curquiza a=Mubelotix Fix #54 Co-authored-by: Mubelotix <[email protected]>
2 parents 20c9d48 + 1e3beb6 commit b0efa85

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed

.code-samples.meilisearch.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,7 @@ faceted_search_walkthrough_facets_distribution_1: |-
540540
.await
541541
.unwrap();
542542
let genres: &HashMap<String, usize> = results.facets_distribution.unwrap().get("genres").unwrap();
543+
post_dump_1: |-
544+
client.create_dump().await.unwrap();
545+
get_dump_status_1: |-
546+
client.get_dump_status("20201101-110357260").await.unwrap();

src/dumps.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//! The `dumps` module allows the creation of database dumps.
2+
//! Dumps are `.dump` files that can be used to launch MeiliSearch.
3+
//! Dumps are compatible between MeiliSearch versions.
4+
//!
5+
//! Creating a dump is also referred to as exporting it, whereas launching MeiliSearch with a dump is referred to as importing it.
6+
//!
7+
//! During a [dump export](Client::create_dump), all [indexes](crate::indexes::Index) of the current instance are exported—together with their documents and settings—and saved as a single `.dump` file.
8+
//!
9+
//! During a dump import, all indexes contained in the indicated `.dump` file are imported along with their associated [documents](crate::document::Document) and [settings](crate::settings::Settings).
10+
//! Any existing [index](crate::indexes::Index) with the same uid as an index in the dump file will be overwritten.
11+
//!
12+
//! Dump imports are [performed at launch](https://docs.meilisearch.com/reference/features/configuration.html#import-dump) using an option.
13+
//! [Batch size](https://docs.meilisearch.com/reference/features/configuration.html#dump-batch-size) can also be set at this time.
14+
//!
15+
//! # Example
16+
//!
17+
//! ```no_run
18+
//! # use meilisearch_sdk::{client::*, errors::*, dumps::*};
19+
//! # use futures_await_test::async_test;
20+
//! # use std::{thread::sleep, time::Duration};
21+
//! # futures::executor::block_on(async move {
22+
//! #
23+
//! let client = Client::new("http://localhost:7700", "masterKey");
24+
//!
25+
//! // Create a dump
26+
//! let dump_info = client.create_dump().await.unwrap();
27+
//! assert!(matches!(dump_info.status, DumpStatus::InProgress));
28+
//!
29+
//! // Wait for MeiliSearch to proceed
30+
//! sleep(Duration::from_secs(5));
31+
//!
32+
//! // Check the status of the dump
33+
//! let dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
34+
//! assert!(matches!(dump_info.status, DumpStatus::Done));
35+
//! # });
36+
//! ```
37+
38+
use crate::{client::Client, errors::Error, request::*};
39+
use serde::Deserialize;
40+
41+
/// The status of a dump.\
42+
/// Contained in [`DumpInfo`].
43+
#[derive(Debug, Deserialize, Clone, PartialEq)]
44+
#[serde(rename_all = "snake_case")]
45+
pub enum DumpStatus {
46+
/// Dump creation is in progress.
47+
Done,
48+
/// Dump creation is in progress.
49+
InProgress,
50+
/// An error occured during dump process, and the task was aborted.
51+
Failed,
52+
}
53+
54+
/// Limited informations about a dump.\
55+
/// Can be obtained with [create_dump](Client::create_dump) and [get_dump_status](Client::get_dump_status) methods.
56+
#[derive(Debug, Deserialize, Clone)]
57+
#[serde(rename_all = "camelCase")]
58+
pub struct DumpInfo {
59+
pub uid: String,
60+
pub status: DumpStatus,
61+
pub error: Option<serde_json::Value>,
62+
}
63+
64+
/// Dump related methods.\
65+
/// See the [dumps](crate::dumps) module.
66+
impl<'a> Client<'a> {
67+
/// Triggers a dump creation process.
68+
/// Once the process is complete, a dump is created in the [dumps directory](https://docs.meilisearch.com/reference/features/configuration.html#dumps-destination).
69+
/// If the dumps directory does not exist yet, it will be created.
70+
///
71+
/// # Example
72+
///
73+
/// ```no_run
74+
/// # use meilisearch_sdk::{client::*, errors::*, dumps::*};
75+
/// # use futures_await_test::async_test;
76+
/// # use std::{thread::sleep, time::Duration};
77+
/// # futures::executor::block_on(async move {
78+
/// #
79+
/// # let client = Client::new("http://localhost:7700", "masterKey");
80+
/// #
81+
/// let dump_info = client.create_dump().await.unwrap();
82+
/// assert!(matches!(dump_info.status, DumpStatus::InProgress));
83+
/// # });
84+
/// ```
85+
pub async fn create_dump(&self) -> Result<DumpInfo, Error> {
86+
request::<(), DumpInfo>(
87+
&format!("{}/dumps", self.host),
88+
self.apikey,
89+
Method::Post(()),
90+
202,
91+
)
92+
.await
93+
}
94+
95+
/// Get the status of a dump creation process using [the uid](DumpInfo::uid) returned after calling the [dump creation method](Client::create_dump).
96+
///
97+
/// # Example
98+
///
99+
/// ```no_run
100+
/// # use meilisearch_sdk::{client::*, errors::*, dumps::*};
101+
/// # use futures_await_test::async_test;
102+
/// # use std::{thread::sleep, time::Duration};
103+
/// # futures::executor::block_on(async move {
104+
/// #
105+
/// # let client = Client::new("http://localhost:7700", "masterKey");
106+
/// # let dump_info = client.create_dump().await.unwrap();
107+
/// # sleep(Duration::from_secs(5));
108+
/// #
109+
/// let dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
110+
/// # });
111+
/// ```
112+
pub async fn get_dump_status(&self, dump_uid: &str) -> Result<DumpInfo, Error> {
113+
request::<(), DumpInfo>(
114+
&format!("{}/dumps/{}/status", self.host, dump_uid),
115+
self.apikey,
116+
Method::Get,
117+
200,
118+
)
119+
.await
120+
}
121+
}
122+
123+
/// Alias for [create_dump](Client::create_dump).
124+
pub async fn create_dump<'a>(client: &'a Client<'a>) -> Result<DumpInfo, Error> {
125+
client.create_dump().await
126+
}
127+
128+
/// Alias for [get_dump_status](Client::get_dump_status).
129+
pub async fn get_dump_status<'a>(
130+
client: &'a Client<'a>,
131+
dump_uid: &str,
132+
) -> Result<DumpInfo, Error> {
133+
client.get_dump_status(dump_uid).await
134+
}
135+
136+
#[cfg(test)]
137+
mod tests {
138+
use super::*;
139+
use crate::client::*;
140+
use futures_await_test::async_test;
141+
use std::{thread::sleep, time::Duration};
142+
143+
#[async_test]
144+
async fn test_dumps() {
145+
let client = Client::new("http://localhost:7700", "masterKey");
146+
147+
// Create a dump
148+
let dump_info = client.create_dump().await.unwrap();
149+
assert!(matches!(dump_info.status, DumpStatus::InProgress));
150+
151+
// Wait for Meilisearch to do the dump
152+
sleep(Duration::from_secs(5));
153+
154+
// Assert that the dump was successful
155+
let new_dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
156+
assert!(matches!(new_dump_info.status, DumpStatus::Done));
157+
}
158+
}

src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ pub enum ErrorCode {
117117
/// The payload content type is not supported by MeiliSearch. Currently,
118118
/// MeiliSearch only supports JSON payloads.
119119
UnsupportedMediaType,
120+
/// A dump creation is already in progress and a new one can't be triggered until the previous dump creation is not finished.
121+
DumpAlreadyInProgress,
122+
/// An error occured during dump creation process, task aborted.
123+
DumpProcessFailed,
120124

121125
/// That's unexpected. Please open a GitHub issue after ensuring you are
122126
/// using the supported version of the MeiliSearch server.
@@ -194,6 +198,8 @@ impl ErrorCode {
194198
ErrorCode::UnretrievableDocument => "unretrievable_document",
195199
ErrorCode::SearchError => "search_error",
196200
ErrorCode::UnsupportedMediaType => "unsupported_media_type",
201+
ErrorCode::DumpAlreadyInProgress => "dump_already_in_progress",
202+
ErrorCode::DumpProcessFailed => "dump_process_failed",
197203
// Other than this variant, all the other `&str`s are 'static
198204
ErrorCode::Unknown(inner) => &inner.0,
199205
}
@@ -227,6 +233,8 @@ impl ErrorCode {
227233
"unretrievable_document" => ErrorCode::UnretrievableDocument,
228234
"search_error" => ErrorCode::SearchError,
229235
"unsupported_media_type" => ErrorCode::UnsupportedMediaType,
236+
"dump_already_in_progress" => ErrorCode::DumpAlreadyInProgress,
237+
"dump_process_failed" => ErrorCode::DumpProcessFailed,
230238
inner => ErrorCode::Unknown(UnknownErrorCode(inner.to_string())),
231239
}
232240
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
pub mod client;
100100
/// Module containing the Document trait.
101101
pub mod document;
102+
pub mod dumps;
102103
/// Module containing the Error struct.
103104
pub mod errors;
104105
/// Module containing the Index struct.

0 commit comments

Comments
 (0)