2022-10-04 00:50:06 +08:00
|
|
|
use std::io::Read;
|
2022-10-03 19:57:18 +08:00
|
|
|
use std::{fs::File, io::BufReader};
|
|
|
|
|
2022-10-06 02:11:07 +08:00
|
|
|
use flate2::bufread::GzDecoder;
|
2022-10-03 19:57:18 +08:00
|
|
|
use index_scheduler::TaskView;
|
|
|
|
use meilisearch_auth::Key;
|
2022-10-06 02:11:07 +08:00
|
|
|
use serde::Deserialize;
|
2022-10-03 19:57:18 +08:00
|
|
|
|
|
|
|
use tempfile::TempDir;
|
|
|
|
use time::OffsetDateTime;
|
2022-10-04 00:50:06 +08:00
|
|
|
use uuid::Uuid;
|
2022-10-03 19:57:18 +08:00
|
|
|
|
2022-10-06 02:11:07 +08:00
|
|
|
use crate::reader::compat::Compat;
|
2022-10-05 01:13:30 +08:00
|
|
|
use crate::{IndexMetadata, Result, Version};
|
2022-10-03 19:57:18 +08:00
|
|
|
|
|
|
|
// use self::loaders::{v2, v3, v4, v5};
|
|
|
|
|
|
|
|
// pub mod error;
|
2022-10-06 02:11:07 +08:00
|
|
|
mod compat;
|
2022-10-03 19:57:18 +08:00
|
|
|
// mod loaders;
|
2022-10-03 22:12:01 +08:00
|
|
|
// mod v1;
|
2022-10-06 02:11:07 +08:00
|
|
|
pub(self) mod v4;
|
|
|
|
pub(self) mod v5;
|
|
|
|
pub(self) mod v6;
|
2022-10-03 19:57:18 +08:00
|
|
|
|
|
|
|
pub fn open(
|
2022-10-04 00:50:06 +08:00
|
|
|
dump: impl Read,
|
2022-10-03 19:57:18 +08:00
|
|
|
) -> Result<
|
2022-10-03 22:12:01 +08:00
|
|
|
Box<
|
|
|
|
dyn DumpReader<
|
|
|
|
Document = serde_json::Map<String, serde_json::Value>,
|
2022-10-06 02:11:07 +08:00
|
|
|
Settings = v6::Settings<v6::Checked>,
|
2022-10-03 22:12:01 +08:00
|
|
|
Task = TaskView,
|
|
|
|
UpdateFile = File,
|
|
|
|
Key = Key,
|
|
|
|
>,
|
2022-10-03 19:57:18 +08:00
|
|
|
>,
|
|
|
|
> {
|
|
|
|
let path = TempDir::new()?;
|
|
|
|
let mut dump = BufReader::new(dump);
|
|
|
|
let gz = GzDecoder::new(&mut dump);
|
|
|
|
let mut archive = tar::Archive::new(gz);
|
|
|
|
archive.unpack(path.path())?;
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
2022-10-04 00:50:06 +08:00
|
|
|
#[serde(rename_all = "camelCase")]
|
2022-10-03 19:57:18 +08:00
|
|
|
struct MetadataVersion {
|
|
|
|
pub dump_version: Version,
|
|
|
|
}
|
|
|
|
let mut meta_file = File::open(path.path().join("metadata.json"))?;
|
|
|
|
let MetadataVersion { dump_version } = serde_json::from_reader(&mut meta_file)?;
|
|
|
|
|
|
|
|
match dump_version {
|
|
|
|
// Version::V1 => Ok(Box::new(v1::Reader::open(path)?)),
|
|
|
|
Version::V1 => todo!(),
|
|
|
|
Version::V2 => todo!(),
|
|
|
|
Version::V3 => todo!(),
|
|
|
|
Version::V4 => todo!(),
|
2022-10-06 02:11:07 +08:00
|
|
|
Version::V5 => {
|
|
|
|
let dump_reader = Box::new(v5::V5Reader::open(path)?);
|
|
|
|
let dump_reader = Box::new(Compat::<
|
|
|
|
dyn DumpReader<
|
|
|
|
Document = v5::Document,
|
|
|
|
Settings = v5::Settings<v5::Checked>,
|
|
|
|
Task = v5::Task,
|
|
|
|
UpdateFile = v5::UpdateFile,
|
|
|
|
Key = v5::Key,
|
|
|
|
>,
|
|
|
|
>::new(dump_reader))
|
|
|
|
as Box<
|
|
|
|
dyn DumpReader<
|
|
|
|
Document = v6::Document,
|
|
|
|
Settings = v6::Settings<v6::Checked>,
|
|
|
|
Task = v6::Task,
|
|
|
|
UpdateFile = v6::UpdateFile,
|
|
|
|
Key = v6::Key,
|
|
|
|
>,
|
|
|
|
>;
|
|
|
|
Ok(dump_reader)
|
|
|
|
}
|
2022-10-03 22:12:01 +08:00
|
|
|
Version::V6 => {
|
|
|
|
let dump_reader = Box::new(v6::V6Reader::open(path)?)
|
|
|
|
as Box<
|
|
|
|
dyn DumpReader<
|
2022-10-06 02:11:07 +08:00
|
|
|
Document = v6::Document,
|
|
|
|
Settings = v6::Settings<v6::Checked>,
|
|
|
|
Task = v6::Task,
|
|
|
|
UpdateFile = v6::UpdateFile,
|
|
|
|
Key = v6::Key,
|
2022-10-03 22:12:01 +08:00
|
|
|
>,
|
|
|
|
>;
|
|
|
|
|
|
|
|
Ok(dump_reader)
|
|
|
|
}
|
|
|
|
}
|
2022-10-03 19:57:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait DumpReader {
|
|
|
|
type Document;
|
|
|
|
type Settings;
|
|
|
|
|
|
|
|
type Task;
|
|
|
|
type UpdateFile;
|
|
|
|
|
|
|
|
type Key;
|
|
|
|
|
|
|
|
/// Return the version of the dump.
|
|
|
|
fn version(&self) -> Version;
|
|
|
|
|
2022-10-04 00:50:06 +08:00
|
|
|
/// Return at which date the dump was created if there was one.
|
2022-10-03 22:12:01 +08:00
|
|
|
fn date(&self) -> Option<OffsetDateTime>;
|
2022-10-03 19:57:18 +08:00
|
|
|
|
2022-10-04 00:50:06 +08:00
|
|
|
/// Return the instance-uid if there was one.
|
|
|
|
fn instance_uid(&self) -> Result<Option<Uuid>>;
|
|
|
|
|
2022-10-03 19:57:18 +08:00
|
|
|
/// Return an iterator over each indexes.
|
|
|
|
fn indexes(
|
|
|
|
&self,
|
|
|
|
) -> Result<
|
|
|
|
Box<
|
|
|
|
dyn Iterator<
|
2022-10-05 01:13:30 +08:00
|
|
|
Item = Result<
|
|
|
|
Box<
|
|
|
|
dyn IndexReader<Document = Self::Document, Settings = Self::Settings>
|
|
|
|
+ '_,
|
|
|
|
>,
|
|
|
|
>,
|
|
|
|
> + '_,
|
2022-10-03 19:57:18 +08:00
|
|
|
>,
|
|
|
|
>;
|
|
|
|
|
|
|
|
/// Return all the tasks in the dump with a possible update file.
|
|
|
|
fn tasks(
|
2022-10-03 22:12:01 +08:00
|
|
|
&mut self,
|
|
|
|
) -> Box<dyn Iterator<Item = Result<(Self::Task, Option<Self::UpdateFile>)>> + '_>;
|
2022-10-03 19:57:18 +08:00
|
|
|
|
|
|
|
/// Return all the keys.
|
2022-10-03 22:12:01 +08:00
|
|
|
fn keys(&mut self) -> Box<dyn Iterator<Item = Result<Self::Key>> + '_>;
|
2022-10-03 19:57:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait IndexReader {
|
|
|
|
type Document;
|
|
|
|
type Settings;
|
|
|
|
|
2022-10-05 01:13:30 +08:00
|
|
|
fn metadata(&self) -> &IndexMetadata;
|
2022-10-03 22:12:01 +08:00
|
|
|
fn documents(&mut self) -> Result<Box<dyn Iterator<Item = Result<Self::Document>> + '_>>;
|
|
|
|
fn settings(&mut self) -> Result<Self::Settings>;
|
2022-10-03 19:57:18 +08:00
|
|
|
}
|