taos_query/common/
describe.rs1use 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}