senax_mysql_parser/
column.rs

1use serde::Deserialize;
2use serde::Serialize;
3use std::fmt;
4use std::str;
5
6use super::common::{Literal, SqlType};
7use super::keywords::escape;
8
9#[derive(Clone, Debug, Eq, Serialize, Deserialize)]
10pub struct Column {
11    pub name: String,
12    pub query: Option<String>,
13    pub len: Option<u32>,
14    pub desc: bool,
15}
16
17impl PartialEq for Column {
18    fn eq(&self, other: &Self) -> bool {
19        if self.query.is_some() && other.query.is_some() {
20            true
21        } else if self.query.is_some() || other.query.is_some() {
22            false
23        } else {
24            self.name == other.name && self.len == other.len && self.desc == other.desc
25        }
26    }
27}
28
29impl fmt::Display for Column {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        if let Some(ref query) = self.query {
32            write!(f, "({})", query)?;
33        } else {
34            write!(f, "{}", escape(&self.name))?;
35            if let Some(ref len) = self.len {
36                write!(f, "({})", len)?;
37            }
38        }
39        if self.desc {
40            write!(f, " DESC")?;
41        }
42        Ok(())
43    }
44}
45
46#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
47pub enum ColumnConstraint {
48    NotNull,
49    CharacterSet(String),
50    Collation(String),
51    DefaultValue(Literal),
52    AutoIncrement,
53    PrimaryKey,
54    Unique,
55    Srid(u32),
56    Generated(String, bool),
57}
58
59impl fmt::Display for ColumnConstraint {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        match self {
62            ColumnConstraint::NotNull => write!(f, "NOT NULL"),
63            ColumnConstraint::CharacterSet(charset) => write!(f, "CHARACTER SET {}", charset),
64            ColumnConstraint::Collation(collation) => write!(f, "COLLATE {}", collation),
65            ColumnConstraint::DefaultValue(literal) => {
66                write!(f, "DEFAULT {}", literal.to_string())
67            }
68            ColumnConstraint::AutoIncrement => write!(f, "AUTO_INCREMENT"),
69            ColumnConstraint::PrimaryKey => write!(f, "PRIMARY KEY"),
70            ColumnConstraint::Unique => write!(f, "UNIQUE"),
71            ColumnConstraint::Srid(srid) => {
72                write!(f, "/*!80003 SRID {} */", srid)
73            }
74            ColumnConstraint::Generated(query, stored) => {
75                write!(
76                    f,
77                    "GENERATED ALWAYS AS ({}) {}",
78                    query,
79                    if *stored { "STORED" } else { "VIRTUAL" }
80                )
81            }
82        }
83    }
84}
85
86#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
87pub struct ColumnSpecification {
88    pub column: Column,
89    pub sql_type: SqlType,
90    pub constraints: Vec<ColumnConstraint>,
91    pub comment: Option<Literal>,
92}
93
94impl ColumnSpecification {
95    pub fn default_value(&self) -> Option<String> {
96        self.constraints
97            .iter()
98            .map(|v| match v {
99                ColumnConstraint::DefaultValue(x) => Some(x.to_raw_string()),
100                _ => None,
101            })
102            .find(|v| v.is_some())
103            .flatten()
104    }
105}
106
107impl fmt::Display for ColumnSpecification {
108    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109        write!(f, "{} {}", escape(&self.column.name), self.sql_type)?;
110        for constraint in self.constraints.iter() {
111            write!(f, " {}", constraint)?;
112        }
113        if let Some(ref comment) = self.comment {
114            write!(f, " COMMENT {}", comment.to_string())?;
115        }
116        Ok(())
117    }
118}