Merge branch 'main' into fix-3037

This commit is contained in:
jiangbo212 2022-11-30 09:38:01 +08:00
commit 9c28632498
173 changed files with 5109 additions and 1714 deletions

View file

@ -147,6 +147,11 @@ pub enum Code {
MissingMasterKey,
NoSpaceLeftOnDevice,
DumpNotFound,
InvalidTaskDateFilter,
InvalidTaskStatusesFilter,
InvalidTaskTypesFilter,
InvalidTaskCanceledByFilter,
InvalidTaskUidsFilter,
TaskNotFound,
TaskDeletionWithEmptyQuery,
TaskCancelationWithEmptyQuery,
@ -239,12 +244,27 @@ impl Code {
MissingMasterKey => {
ErrCode::authentication("missing_master_key", StatusCode::UNAUTHORIZED)
}
InvalidTaskDateFilter => {
ErrCode::invalid("invalid_task_date_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskUidsFilter => {
ErrCode::invalid("invalid_task_uids_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskStatusesFilter => {
ErrCode::invalid("invalid_task_statuses_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskTypesFilter => {
ErrCode::invalid("invalid_task_types_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskCanceledByFilter => {
ErrCode::invalid("invalid_task_canceled_by_filter", StatusCode::BAD_REQUEST)
}
TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND),
TaskDeletionWithEmptyQuery => {
ErrCode::invalid("missing_filters", StatusCode::BAD_REQUEST)
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
}
TaskCancelationWithEmptyQuery => {
ErrCode::invalid("missing_filters", StatusCode::BAD_REQUEST)
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
}
DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND),
NoSpaceLeftOnDevice => {

View file

@ -75,9 +75,9 @@ impl fmt::Display for IndexUidFormatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"invalid index uid `{}`, the uid must be an integer \
or a string containing only alphanumeric characters \
a-z A-Z 0-9, hyphens - and underscores _.",
"`{}` is not a valid index uid. Index uid can be an \
integer or a string containing only alphanumeric \
characters, hyphens (-) and underscores (_).",
self.invalid_uid,
)
}

View file

@ -1,4 +1,5 @@
use std::hash::Hash;
use std::str::FromStr;
use enum_iterator::Sequence;
use serde::{Deserialize, Serialize};
@ -9,7 +10,7 @@ use time::{Date, OffsetDateTime, PrimitiveDateTime};
use uuid::Uuid;
use crate::error::{Code, ErrorCode};
use crate::index_uid::IndexUid;
use crate::index_uid::{IndexUid, IndexUidFormatError};
use crate::star_or::StarOr;
type Result<T> = std::result::Result<T, Error>;
@ -64,7 +65,15 @@ impl Key {
let indexes = value
.get("indexes")
.map(|ind| {
from_value(ind.clone()).map_err(|_| Error::InvalidApiKeyIndexes(ind.clone()))
from_value::<Vec<String>>(ind.clone())
// If it's not a vec of string, return an API key parsing error.
.map_err(|_| Error::InvalidApiKeyIndexes(ind.clone()))
.and_then(|ind| {
ind.into_iter()
// If it's not a valid Index uid, return an Index Uid parsing error.
.map(|i| StarOr::<IndexUid>::from_str(&i).map_err(Error::from))
.collect()
})
})
.ok_or(Error::MissingParameter("indexes"))??;
@ -339,10 +348,10 @@ pub enum Error {
MissingParameter(&'static str),
#[error("`actions` field value `{0}` is invalid. It should be an array of string representing action names.")]
InvalidApiKeyActions(Value),
#[error(
"`{0}` is not a valid index uid. It should be an array of string representing index names."
)]
#[error("`indexes` field value `{0}` is invalid. It should be an array of string representing index names.")]
InvalidApiKeyIndexes(Value),
#[error("{0}")]
InvalidApiKeyIndexUid(IndexUidFormatError),
#[error("`expiresAt` field value `{0}` is invalid. It should follow the RFC 3339 format to represents a date or datetime in the future or specified as a null value. e.g. 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS'.")]
InvalidApiKeyExpiresAt(Value),
#[error("`description` field value `{0}` is invalid. It should be a string or specified as a null value.")]
@ -357,12 +366,20 @@ pub enum Error {
ImmutableField(String),
}
impl From<IndexUidFormatError> for Error {
fn from(e: IndexUidFormatError) -> Self {
Self::InvalidApiKeyIndexUid(e)
}
}
impl ErrorCode for Error {
fn error_code(&self) -> Code {
match self {
Self::MissingParameter(_) => Code::MissingParameter,
Self::InvalidApiKeyActions(_) => Code::InvalidApiKeyActions,
Self::InvalidApiKeyIndexes(_) => Code::InvalidApiKeyIndexes,
Self::InvalidApiKeyIndexes(_) | Self::InvalidApiKeyIndexUid(_) => {
Code::InvalidApiKeyIndexes
}
Self::InvalidApiKeyExpiresAt(_) => Code::InvalidApiKeyExpiresAt,
Self::InvalidApiKeyDescription(_) => Code::InvalidApiKeyDescription,
Self::InvalidApiKeyName(_) => Code::InvalidApiKeyName,

View file

@ -127,7 +127,6 @@ pub enum KindWithContent {
tasks: RoaringBitmap,
},
DumpCreation {
dump_uid: String,
keys: Vec<Key>,
instance_uid: Option<InstanceUid>,
},
@ -196,17 +195,16 @@ impl KindWithContent {
}
KindWithContent::DocumentDeletion { index_uid: _, documents_ids } => {
Some(Details::DocumentDeletion {
matched_documents: documents_ids.len(),
provided_ids: documents_ids.len(),
deleted_documents: None,
})
}
KindWithContent::DocumentClear { .. } => {
KindWithContent::DocumentClear { .. } | KindWithContent::IndexDeletion { .. } => {
Some(Details::ClearAll { deleted_documents: None })
}
KindWithContent::SettingsUpdate { new_settings, .. } => {
Some(Details::SettingsUpdate { settings: new_settings.clone() })
}
KindWithContent::IndexDeletion { .. } => None,
KindWithContent::IndexCreation { primary_key, .. }
| KindWithContent::IndexUpdate { primary_key, .. } => {
Some(Details::IndexInfo { primary_key: primary_key.clone() })
@ -217,14 +215,14 @@ impl KindWithContent {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: None,
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: None,
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::DumpCreation { .. } => None,
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
KindWithContent::SnapshotCreation => None,
}
}
@ -239,7 +237,7 @@ impl KindWithContent {
}
KindWithContent::DocumentDeletion { index_uid: _, documents_ids } => {
Some(Details::DocumentDeletion {
matched_documents: documents_ids.len(),
provided_ids: documents_ids.len(),
deleted_documents: Some(0),
})
}
@ -260,14 +258,14 @@ impl KindWithContent {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: Some(0),
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: Some(0),
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::DumpCreation { .. } => None,
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
KindWithContent::SnapshotCreation => None,
}
}
@ -298,16 +296,14 @@ impl From<&KindWithContent> for Option<Details> {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: None,
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: None,
original_query: query.clone(),
original_filter: query.clone(),
}),
KindWithContent::DumpCreation { dump_uid, .. } => {
Some(Details::Dump { dump_uid: dump_uid.clone() })
}
KindWithContent::DumpCreation { .. } => Some(Details::Dump { dump_uid: None }),
KindWithContent::SnapshotCreation => None,
}
}
@ -398,7 +394,23 @@ impl Kind {
}
}
}
impl Display for Kind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Kind::DocumentAdditionOrUpdate => write!(f, "documentAdditionOrUpdate"),
Kind::DocumentDeletion => write!(f, "documentDeletion"),
Kind::SettingsUpdate => write!(f, "settingsUpdate"),
Kind::IndexCreation => write!(f, "indexCreation"),
Kind::IndexDeletion => write!(f, "indexDeletion"),
Kind::IndexUpdate => write!(f, "indexUpdate"),
Kind::IndexSwap => write!(f, "indexSwap"),
Kind::TaskCancelation => write!(f, "taskCancelation"),
Kind::TaskDeletion => write!(f, "taskDeletion"),
Kind::DumpCreation => write!(f, "dumpCreation"),
Kind::SnapshotCreation => write!(f, "snapshotCreation"),
}
}
}
impl FromStr for Kind {
type Err = ResponseError;
@ -450,14 +462,35 @@ pub enum Details {
DocumentAdditionOrUpdate { received_documents: u64, indexed_documents: Option<u64> },
SettingsUpdate { settings: Box<Settings<Unchecked>> },
IndexInfo { primary_key: Option<String> },
DocumentDeletion { matched_documents: usize, deleted_documents: Option<u64> },
DocumentDeletion { provided_ids: usize, deleted_documents: Option<u64> },
ClearAll { deleted_documents: Option<u64> },
TaskCancelation { matched_tasks: u64, canceled_tasks: Option<u64>, original_query: String },
TaskDeletion { matched_tasks: u64, deleted_tasks: Option<u64>, original_query: String },
Dump { dump_uid: String },
TaskCancelation { matched_tasks: u64, canceled_tasks: Option<u64>, original_filter: String },
TaskDeletion { matched_tasks: u64, deleted_tasks: Option<u64>, original_filter: String },
Dump { dump_uid: Option<String> },
IndexSwap { swaps: Vec<IndexSwap> },
}
impl Details {
pub fn to_failed(&self) -> Self {
let mut details = self.clone();
match &mut details {
Self::DocumentAdditionOrUpdate { indexed_documents, .. } => {
*indexed_documents = Some(0)
}
Self::DocumentDeletion { deleted_documents, .. } => *deleted_documents = Some(0),
Self::ClearAll { deleted_documents } => *deleted_documents = Some(0),
Self::TaskCancelation { canceled_tasks, .. } => *canceled_tasks = Some(0),
Self::TaskDeletion { deleted_tasks, .. } => *deleted_tasks = Some(0),
Self::SettingsUpdate { .. }
| Self::IndexInfo { .. }
| Self::Dump { .. }
| Self::IndexSwap { .. } => (),
}
details
}
}
/// Serialize a `time::Duration` as a best effort ISO 8601 while waiting for
/// https://github.com/time-rs/time/issues/378.
/// This code is a port of the old code of time that was removed in 0.2.
@ -520,11 +553,11 @@ mod tests {
let details = Details::TaskDeletion {
matched_tasks: 1,
deleted_tasks: None,
original_query: "hello".to_owned(),
original_filter: "hello".to_owned(),
};
let serialised = SerdeJson::<Details>::bytes_encode(&details).unwrap();
let deserialised = SerdeJson::<Details>::bytes_decode(&serialised).unwrap();
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_query: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_query: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filter: "hello" }"###);
}
}