taos_query/common/
describe.rs

1use std::ops::{Deref, DerefMut};
2
3use itertools::Itertools;
4use serde::{Deserialize, Serialize};
5
6use crate::helpers::ColumnMeta;
7
8#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
9pub struct Describe(pub(crate) Vec<ColumnMeta>);
10
11impl IntoIterator for Describe {
12    type Item = ColumnMeta;
13
14    type IntoIter = std::vec::IntoIter<Self::Item>;
15
16    fn into_iter(self) -> Self::IntoIter {
17        self.0.into_iter()
18    }
19}
20
21impl FromIterator<ColumnMeta> for Describe {
22    fn from_iter<T: IntoIterator<Item = ColumnMeta>>(iter: T) -> Self {
23        Describe(iter.into_iter().collect())
24    }
25}
26
27impl Deref for Describe {
28    type Target = Vec<ColumnMeta>;
29
30    fn deref(&self) -> &Self::Target {
31        &self.0
32    }
33}
34
35impl DerefMut for Describe {
36    fn deref_mut(&mut self) -> &mut Self::Target {
37        &mut self.0
38    }
39}
40impl Describe {
41    #[inline]
42    fn fields(&self) -> &[ColumnMeta] {
43        &self.0
44    }
45    pub fn is_stable(&self) -> bool {
46        self.fields().iter().any(|f| f.is_tag())
47    }
48    pub fn names(&self) -> impl Iterator<Item = &str> {
49        self.fields().iter().map(|f| f.field())
50    }
51
52    pub fn split(&self) -> Option<(&[ColumnMeta], &[ColumnMeta])> {
53        if let Some((at, _)) = self.deref().iter().find_position(|c| c.is_tag()) {
54            Some(self.deref().split_at(at))
55        } else {
56            Some(self.deref().split_at(self.0.len()))
57        }
58    }
59
60    pub fn tag_names(&self) -> impl Iterator<Item = &str> {
61        self.fields()
62            .iter()
63            .filter(|f| f.is_tag())
64            .map(|f| f.field())
65    }
66    pub fn to_create_table_sql(&self, table: &str) -> String {
67        let (cols, tags): (Vec<_>, Vec<_>) = self.fields().iter().partition(|f| !f.is_tag());
68        let col_sql = cols.into_iter().map(|f| f.sql_repr()).join(",");
69
70        if tags.is_empty() {
71            format!("create table if not exists `{table}` ({col_sql})")
72        } else {
73            let tags_sql = tags.into_iter().map(|f| f.sql_repr()).join(",");
74            format!("create table if not exists `{table}` ({col_sql}) tags({tags_sql})")
75        }
76    }
77}