107 lines
2.3 KiB
Rust
107 lines
2.3 KiB
Rust
use crate::idx::ft::analyzer::Analyzers;
|
|
use crate::sql::comment::{mightbespace, shouldbespace};
|
|
use crate::sql::error::IResult;
|
|
use crate::sql::ident::{ident, Ident};
|
|
use crate::sql::scoring::{scoring, Scoring};
|
|
use nom::branch::alt;
|
|
use nom::bytes::complete::{tag, tag_no_case};
|
|
use nom::character::complete::u32;
|
|
use nom::combinator::{map, opt};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fmt;
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
|
|
pub enum Index {
|
|
/// (Basic) non unique
|
|
Idx,
|
|
/// Unique index
|
|
Uniq,
|
|
/// Index with Full-Text search capabilities
|
|
Search {
|
|
az: Ident,
|
|
hl: bool,
|
|
sc: Scoring,
|
|
order: u32,
|
|
},
|
|
}
|
|
|
|
impl Default for Index {
|
|
fn default() -> Self {
|
|
Self::Idx
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Index {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Self::Idx => Ok(()),
|
|
Self::Uniq => f.write_str("UNIQUE"),
|
|
Self::Search {
|
|
az,
|
|
hl,
|
|
sc,
|
|
order,
|
|
} => {
|
|
write!(f, "SEARCH ANALYZER {} {} ORDER {}", az, sc, order)?;
|
|
if *hl {
|
|
f.write_str(" HIGHLIGHTS")?
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn index(i: &str) -> IResult<&str, Index> {
|
|
alt((unique, search, non_unique))(i)
|
|
}
|
|
|
|
pub fn non_unique(i: &str) -> IResult<&str, Index> {
|
|
let (i, _) = tag("")(i)?;
|
|
Ok((i, Index::Idx))
|
|
}
|
|
|
|
pub fn unique(i: &str) -> IResult<&str, Index> {
|
|
let (i, _) = tag_no_case("UNIQUE")(i)?;
|
|
Ok((i, Index::Uniq))
|
|
}
|
|
|
|
pub fn analyzer(i: &str) -> IResult<&str, Ident> {
|
|
let (i, _) = mightbespace(i)?;
|
|
let (i, _) = tag_no_case("ANALYZER")(i)?;
|
|
let (i, _) = shouldbespace(i)?;
|
|
let (i, analyzer) = ident(i)?;
|
|
Ok((i, analyzer))
|
|
}
|
|
|
|
pub fn order(i: &str) -> IResult<&str, u32> {
|
|
let (i, _) = mightbespace(i)?;
|
|
let (i, _) = tag_no_case("ORDER")(i)?;
|
|
let (i, _) = shouldbespace(i)?;
|
|
let (i, order) = u32(i)?;
|
|
Ok((i, order))
|
|
}
|
|
|
|
pub fn highlights(i: &str) -> IResult<&str, bool> {
|
|
let (i, _) = mightbespace(i)?;
|
|
alt((map(tag("HIGHLIGHTS"), |_| true), map(tag(""), |_| false)))(i)
|
|
}
|
|
|
|
pub fn search(i: &str) -> IResult<&str, Index> {
|
|
let (i, _) = tag_no_case("SEARCH")(i)?;
|
|
let (i, _) = shouldbespace(i)?;
|
|
let (i, az) = opt(analyzer)(i)?;
|
|
let (i, _) = shouldbespace(i)?;
|
|
let (i, sc) = scoring(i)?;
|
|
let (i, o) = opt(order)(i)?;
|
|
let (i, hl) = highlights(i)?;
|
|
Ok((
|
|
i,
|
|
Index::Search {
|
|
az: az.unwrap_or_else(|| Ident::from(Analyzers::LIKE)),
|
|
sc,
|
|
hl,
|
|
order: o.unwrap_or(100),
|
|
},
|
|
))
|
|
}
|