1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! The `dumps` module allows the creation of database dumps.
//! Dumps are `.dump` files that can be used to launch MeiliSearch.
//! Dumps are compatible between MeiliSearch versions.
//!
//! Creating a dump is also referred to as exporting it, whereas launching MeiliSearch with a dump is referred to as importing it.
//!
//! 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.
//!
//! 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).
//! Any existing [index](crate::indexes::Index) with the same uid as an index in the dump file will be overwritten.
//!
//! Dump imports are [performed at launch](https://docs.meilisearch.com/reference/features/configuration.html#import-dump) using an option.
//! [Batch size](https://docs.meilisearch.com/reference/features/configuration.html#dump-batch-size) can also be set at this time.
//!
//! # Example
//!
//! ```no_run
//! # use meilisearch_sdk::{client::*, errors::*, dumps::*};
//! # use futures_await_test::async_test;
//! # use std::{thread::sleep, time::Duration};
//! # futures::executor::block_on(async move {
//! #
//! let client = Client::new("http://localhost:7700", "masterKey");
//!
//! // Create a dump
//! let dump_info = client.create_dump().await.unwrap();
//! assert!(matches!(dump_info.status, DumpStatus::InProgress));
//!
//! // Wait for MeiliSearch to proceed
//! sleep(Duration::from_secs(5));
//!
//! // Check the status of the dump
//! let dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
//! assert!(matches!(dump_info.status, DumpStatus::Done));
//! # });
//! ```

use crate::{client::Client, errors::Error, request::*};
use serde::Deserialize;

/// The status of a dump.\
/// Contained in [`DumpInfo`].
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum DumpStatus {
    /// Dump creation is in progress.
    Done,
    /// Dump creation is in progress.
    InProgress,
    /// An error occured during dump process, and the task was aborted.
    Failed,
}

/// Limited informations about a dump.\
/// Can be obtained with [create_dump](Client::create_dump) and [get_dump_status](Client::get_dump_status) methods.
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DumpInfo {
    pub uid: String,
    pub status: DumpStatus,
    pub error: Option<serde_json::Value>,
}

/// Dump related methods.\
/// See the [dumps](crate::dumps) module.
impl<'a> Client<'a> {
    /// Triggers a dump creation process.
    /// Once the process is complete, a dump is created in the [dumps directory](https://docs.meilisearch.com/reference/features/configuration.html#dumps-destination).
    /// If the dumps directory does not exist yet, it will be created.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # use meilisearch_sdk::{client::*, errors::*, dumps::*};
    /// # use futures_await_test::async_test;
    /// # use std::{thread::sleep, time::Duration};
    /// # futures::executor::block_on(async move {
    /// #
    /// # let client = Client::new("http://localhost:7700", "masterKey");
    /// #
    /// let dump_info = client.create_dump().await.unwrap();
    /// assert!(matches!(dump_info.status, DumpStatus::InProgress));
    /// # });
    /// ```
    pub async fn create_dump(&self) -> Result<DumpInfo, Error> {
        request::<(), DumpInfo>(
            &format!("{}/dumps", self.host),
            self.apikey,
            Method::Post(()),
            202,
        )
        .await
    }

    /// Get the status of a dump creation process using [the uid](DumpInfo::uid) returned after calling the [dump creation method](Client::create_dump).
    ///
    /// # Example
    ///
    /// ```no_run
    /// # use meilisearch_sdk::{client::*, errors::*, dumps::*};
    /// # use futures_await_test::async_test;
    /// # use std::{thread::sleep, time::Duration};
    /// # futures::executor::block_on(async move {
    /// #
    /// # let client = Client::new("http://localhost:7700", "masterKey");
    /// # let dump_info = client.create_dump().await.unwrap();
    /// # sleep(Duration::from_secs(5));
    /// #
    /// let dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
    /// # });
    /// ```
    pub async fn get_dump_status(&self, dump_uid: &str) -> Result<DumpInfo, Error> {
        request::<(), DumpInfo>(
            &format!("{}/dumps/{}/status", self.host, dump_uid),
            self.apikey,
            Method::Get,
            200,
        )
        .await
    }
}

/// Alias for [create_dump](Client::create_dump).
pub async fn create_dump<'a>(client: &'a Client<'a>) -> Result<DumpInfo, Error> {
    client.create_dump().await
}

/// Alias for [get_dump_status](Client::get_dump_status).
pub async fn get_dump_status<'a>(
    client: &'a Client<'a>,
    dump_uid: &str,
) -> Result<DumpInfo, Error> {
    client.get_dump_status(dump_uid).await
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::client::*;
    use futures_await_test::async_test;
    use std::{thread::sleep, time::Duration};

    #[async_test]
    async fn test_dumps() {
        let client = Client::new("http://localhost:7700", "masterKey");

        // Create a dump
        let dump_info = client.create_dump().await.unwrap();
        assert!(matches!(dump_info.status, DumpStatus::InProgress));

        // Wait for Meilisearch to do the dump
        sleep(Duration::from_secs(5));

        // Assert that the dump was successful
        let new_dump_info = client.get_dump_status(&dump_info.uid).await.unwrap();
        assert!(matches!(new_dump_info.status, DumpStatus::Done));
    }
}