kassandra/cql/schema/
table.rs1use std::slice;
2
3use indexmap::map::IndexMap;
4use serde::{Deserialize, Serialize};
5
6use super::ColumnType;
7use crate::cql::schema::Column;
8
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct Table {
11    pub keyspace: String,
12    pub name: String,
13    pub schema: TableSchema,
14}
15
16#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
17pub struct TableSchema {
18    pub columns: IndexMap<String, Column>,
19    pub partition_key: PrimaryKey,
20    pub clustering_key: PrimaryKey,
21    pub partitioner: Option<String>,
22}
23
24impl TableSchema {
25    pub fn clustering_key_column(&self) -> PrimaryKeyColumn {
26        PrimaryKeyColumn::new(self.clustering_key.into_iter(), &self.columns)
27    }
28    pub fn partition_key_column(&self) -> PrimaryKeyColumn {
29        PrimaryKeyColumn::new(self.partition_key.into_iter(), &self.columns)
30    }
31}
32
33#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
34pub enum PrimaryKey {
35    Empty,
36    Simple(String),
37    Composite(Vec<String>),
38}
39
40impl PrimaryKey {
41    pub fn count(&self) -> usize {
42        match self {
43            PrimaryKey::Empty => 0,
44            PrimaryKey::Simple(_) => 1,
45            PrimaryKey::Composite(v) => v.len(),
46        }
47    }
48    pub fn from_definition(mut names: Vec<String>) -> PrimaryKey {
49        match names.len() {
50            0 => PrimaryKey::Empty,
51            1 => PrimaryKey::Simple(names.pop().unwrap()),
52            _ => PrimaryKey::Composite(names),
53        }
54    }
55}
56
57impl<'a> IntoIterator for &'a PrimaryKey {
58    type Item = &'a String;
59    type IntoIter = slice::Iter<'a, String>;
60
61    fn into_iter(self) -> Self::IntoIter {
62        match self {
63            PrimaryKey::Empty => slice::Iter::default(),
64            PrimaryKey::Simple(v) => slice::from_ref(v).iter(),
65            PrimaryKey::Composite(v) => v.iter(),
66        }
67    }
68}
69
70#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
71pub enum PrimaryKeyColumn {
72    Empty,
73    Simple(ColumnType),
74    Composite(Vec<ColumnType>),
75}
76
77impl PrimaryKeyColumn {
78    fn new<'a>(
79        mut names: impl Iterator<Item = &'a String>,
80        def: &'a IndexMap<String, Column>,
81    ) -> Self {
82        let Some(first) = names.next() else {
83            return Self::Empty;
84        };
85        let first = def.get(first).cloned().unwrap().ty;
86
87        let Some(next) = names.next() else {
88            return Self::Simple(first);
89        };
90
91        let tail = std::iter::once(next)
92            .chain(names)
93            .map(|it| def.get(it).unwrap().clone().ty);
94
95        Self::Composite(std::iter::once(first).chain(tail).collect())
96    }
97
98    pub fn size(&self) -> usize {
99        match self {
100            PrimaryKeyColumn::Empty => 0,
101            PrimaryKeyColumn::Simple(_) => 1,
102            PrimaryKeyColumn::Composite(v) => v.len(),
103        }
104    }
105}
106
107impl<'a> IntoIterator for &'a PrimaryKeyColumn {
108    type Item = &'a ColumnType;
109    type IntoIter = slice::Iter<'a, ColumnType>;
110
111    fn into_iter(self) -> Self::IntoIter {
112        match self {
113            PrimaryKeyColumn::Empty => slice::Iter::default(),
114            PrimaryKeyColumn::Simple(v) => slice::from_ref(v).iter(),
115            PrimaryKeyColumn::Composite(v) => v.iter(),
116        }
117    }
118}