#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use use_db_name::{ColumnName, IndexName, TableName};
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IndexRef {
name: Option<IndexName>,
table: Option<TableName>,
}
impl IndexRef {
#[must_use]
pub const fn new(name: Option<IndexName>, table: Option<TableName>) -> Self {
Self { name, table }
}
#[must_use]
pub const fn name(&self) -> Option<&IndexName> {
self.name.as_ref()
}
#[must_use]
pub const fn table(&self) -> Option<&TableName> {
self.table.as_ref()
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum IndexKind {
#[default]
BTree,
Hash,
FullText,
Spatial,
Other,
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum IndexOrder {
#[default]
Ascending,
Descending,
Default,
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum IndexUniqueness {
#[default]
NonUnique,
Unique,
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IndexColumn {
column: ColumnName,
order: IndexOrder,
}
impl IndexColumn {
#[must_use]
pub const fn new(column: ColumnName, order: IndexOrder) -> Self {
Self { column, order }
}
#[must_use]
pub const fn column(&self) -> &ColumnName {
&self.column
}
#[must_use]
pub const fn order(&self) -> IndexOrder {
self.order
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct IndexMetadata {
reference: IndexRef,
kind: IndexKind,
columns: Vec<IndexColumn>,
uniqueness: IndexUniqueness,
}
impl IndexMetadata {
#[must_use]
pub const fn new(reference: IndexRef) -> Self {
Self {
reference,
kind: IndexKind::BTree,
columns: Vec::new(),
uniqueness: IndexUniqueness::NonUnique,
}
}
#[must_use]
pub const fn with_kind(mut self, kind: IndexKind) -> Self {
self.kind = kind;
self
}
#[must_use]
pub fn with_columns(mut self, columns: Vec<IndexColumn>) -> Self {
self.columns = columns;
self
}
#[must_use]
pub const fn with_uniqueness(mut self, uniqueness: IndexUniqueness) -> Self {
self.uniqueness = uniqueness;
self
}
#[must_use]
pub const fn reference(&self) -> &IndexRef {
&self.reference
}
#[must_use]
pub fn columns(&self) -> &[IndexColumn] {
&self.columns
}
#[must_use]
pub const fn uniqueness(&self) -> IndexUniqueness {
self.uniqueness
}
}
#[cfg(test)]
mod tests {
use super::{IndexColumn, IndexMetadata, IndexOrder, IndexRef, IndexUniqueness};
use use_db_name::{ColumnName, IndexName, TableName};
#[test]
fn stores_index_metadata() -> Result<(), Box<dyn std::error::Error>> {
let reference = IndexRef::new(
Some(IndexName::new("users_id_idx")?),
Some(TableName::new("users")?),
);
let column = IndexColumn::new(ColumnName::new("id")?, IndexOrder::Ascending);
let metadata = IndexMetadata::new(reference)
.with_columns(vec![column])
.with_uniqueness(IndexUniqueness::Unique);
assert_eq!(
metadata.reference().name().expect("name").as_str(),
"users_id_idx"
);
assert_eq!(metadata.columns()[0].order(), IndexOrder::Ascending);
assert_eq!(metadata.uniqueness(), IndexUniqueness::Unique);
Ok(())
}
}