Skip to main content

elefant_tools/models/
column.rs

1use crate::postgres_client_wrapper::FromPgChar;
2use crate::quoting::{AttemptedKeywordUsage, IdentifierQuoter, Quotable};
3use crate::{ElefantToolsError, PostgresSchema, PostgresTable};
4use serde::{Deserialize, Serialize};
5use AttemptedKeywordUsage::Other;
6
7#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
8pub struct PostgresColumn {
9    pub name: String,
10    pub ordinal_position: i32,
11    pub is_nullable: bool,
12    pub data_type: String,
13    pub default_value: Option<String>,
14    pub generated: Option<GeneratedColumn>,
15    pub comment: Option<String>,
16    pub array_dimensions: i32,
17    pub data_type_length: Option<i32>,
18    pub identity: Option<ColumnIdentity>,
19}
20
21#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
22pub struct GeneratedColumn {
23    pub expression: String,
24    pub generation_type: GeneratedColumnType,
25}
26
27#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
28pub enum GeneratedColumnType {
29    Stored,
30    Virtual,
31}
32
33impl PostgresColumn {
34    pub fn get_alter_table_set_default_statement(
35        &self,
36        table: &PostgresTable,
37        schema: &PostgresSchema,
38        identifier_quoter: &IdentifierQuoter,
39    ) -> Option<String> {
40        self.default_value.as_ref().map(|default_value| {
41            format!(
42                "alter table {}.{} alter column {} set default {};",
43                schema.name.quote(identifier_quoter, Other),
44                table.name.quote(identifier_quoter, Other),
45                self.name.quote(identifier_quoter, Other),
46                default_value
47            )
48        })
49    }
50}
51
52impl PostgresColumn {
53    pub fn get_simplified_data_type(&self) -> SimplifiedDataType {
54        if self.array_dimensions > 0 {
55            return SimplifiedDataType::Text;
56        }
57        match self.data_type.as_str() {
58            "int2" | "int4" | "int8" | "float4" | "float8" => SimplifiedDataType::Number,
59            "boolean" => SimplifiedDataType::Bool,
60            _ => SimplifiedDataType::Text,
61        }
62    }
63}
64
65impl Default for PostgresColumn {
66    fn default() -> Self {
67        Self {
68            name: "".to_string(),
69            ordinal_position: 0,
70            is_nullable: true,
71            data_type: "".to_string(),
72            default_value: None,
73            generated: None,
74            comment: None,
75            array_dimensions: 0,
76            data_type_length: None,
77            identity: None,
78        }
79    }
80}
81
82#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
83pub enum SimplifiedDataType {
84    Number,
85    Text,
86    Bool,
87}
88
89#[derive(Debug, Eq, PartialEq, Copy, Clone, Serialize, Deserialize)]
90pub enum ColumnIdentity {
91    GeneratedAlways,
92    GeneratedByDefault,
93}
94
95impl FromPgChar for ColumnIdentity {
96    fn from_pg_char(c: char) -> Result<Self, ElefantToolsError> {
97        match c {
98            'a' => Ok(ColumnIdentity::GeneratedAlways),
99            'd' => Ok(ColumnIdentity::GeneratedByDefault),
100            _ => Err(ElefantToolsError::UnknownColumnIdentity(c.to_string())),
101        }
102    }
103}