mod schema;
use serde::{Deserialize, Serialize};
use crate::{CollectionSchema, DataRecord, StorageError, StorageLocator};
use super::{ApplyDefaultLocator, HasLocator};
pub use schema::{
AddColumnsRequest, AlterColumnsRequest, ColumnAlterationSpec, ComputedColumn,
DropColumnsRequest, SchemaEvolutionRequest,
};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct CollectionInfo {
pub locator: StorageLocator,
pub schema: Option<CollectionSchema>,
pub record_count: Option<u64>,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum CreateCollectionMode {
Create,
Overwrite,
CreateIfMissing,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum CreateCollectionAction {
Create,
Recreate,
Reuse,
ErrorExists,
}
impl CreateCollectionMode {
pub(crate) fn resolve(self, exists: bool) -> CreateCollectionAction {
match (self, exists) {
(Self::Create, true) => CreateCollectionAction::ErrorExists,
(Self::Create, false) => CreateCollectionAction::Create,
(Self::Overwrite, true) => CreateCollectionAction::Recreate,
(Self::Overwrite, false) => CreateCollectionAction::Create,
(Self::CreateIfMissing, true) => CreateCollectionAction::Reuse,
(Self::CreateIfMissing, false) => CreateCollectionAction::Create,
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct CreateCollectionRequest {
pub locator: StorageLocator,
pub schema: Option<CollectionSchema>,
pub records: Vec<DataRecord>,
pub mode: CreateCollectionMode,
}
impl HasLocator for CreateCollectionRequest {
fn locator_mut(&mut self) -> &mut StorageLocator {
&mut self.locator
}
}
impl CreateCollectionRequest {
pub(crate) fn already_exists_error(&self, noun: &'static str) -> StorageError {
StorageError::backend_op(
"create_collection",
format!("{noun} `{}` already exists", self.locator.collection),
)
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ListCollectionsRequest {
pub namespace: Vec<String>,
pub limit: Option<u32>,
pub start_after: Option<String>,
}
impl ListCollectionsRequest {
fn apply_default_namespace(mut self, default: &StorageLocator) -> Self {
if self.namespace.is_empty() {
self.namespace = default.namespace.clone();
}
self
}
pub(crate) fn apply_to_collections(
&self,
mut collections: Vec<CollectionInfo>,
) -> Vec<CollectionInfo> {
collections.sort_by(|left, right| left.locator.collection.cmp(&right.locator.collection));
if let Some(start_after) = self.start_after.as_deref() {
collections.retain(|info| info.locator.collection.as_str() > start_after);
}
if let Some(limit) = self.limit {
collections.truncate(limit as usize);
}
collections
}
}
impl ApplyDefaultLocator for ListCollectionsRequest {
fn apply_default_locator(self, default: &StorageLocator) -> Self {
self.apply_default_namespace(default)
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum CatalogRequest {
CreateCollection(CreateCollectionRequest),
OpenCollection {
locator: StorageLocator,
},
ListCollections(ListCollectionsRequest),
DropCollection {
locator: StorageLocator,
ignore_missing: bool,
},
AlterCollection(SchemaEvolutionRequest),
}
impl ApplyDefaultLocator for CatalogRequest {
fn apply_default_locator(self, default: &StorageLocator) -> Self {
match self {
Self::CreateCollection(request) => {
Self::CreateCollection(request.apply_default_locator(default))
}
Self::OpenCollection { locator } => Self::OpenCollection {
locator: locator.with_defaults_from(default),
},
Self::ListCollections(request) => {
Self::ListCollections(request.apply_default_locator(default))
}
Self::DropCollection {
locator,
ignore_missing,
} => Self::DropCollection {
locator: locator.with_defaults_from(default),
ignore_missing,
},
Self::AlterCollection(request) => {
Self::AlterCollection(request.apply_default_locator(default))
}
}
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum CatalogResponse {
Completed,
Collection(CollectionInfo),
Collections(Vec<CollectionInfo>),
}