Skip to main content

elefant_tools/models/
sequence.rs

1use crate::object_id::ObjectId;
2use crate::quoting::AttemptedKeywordUsage::ColumnName;
3use crate::quoting::{quote_value_string, IdentifierQuoter, Quotable};
4use crate::PostgresSchema;
5use serde::{Deserialize, Serialize};
6use std::cmp::Ordering;
7
8#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
9pub struct PostgresSequence {
10    pub name: String,
11    pub data_type: String,
12    pub start_value: i64,
13    pub increment: i64,
14    pub min_value: i64,
15    pub max_value: i64,
16    pub cache_size: i64,
17    pub cycle: bool,
18    pub last_value: Option<i64>,
19    pub comment: Option<String>,
20    pub object_id: ObjectId,
21    pub is_internally_created: bool,
22    pub author_table: Option<String>,
23    pub author_table_column_position: Option<i32>,
24}
25
26impl Default for PostgresSequence {
27    fn default() -> Self {
28        Self {
29            name: String::new(),
30            data_type: String::new(),
31            start_value: 1,
32            increment: 1,
33            min_value: 1,
34            max_value: 2147483647,
35            cache_size: 1,
36            cycle: false,
37            last_value: None,
38            comment: None,
39            object_id: ObjectId::default(),
40            is_internally_created: false,
41            author_table: None,
42            author_table_column_position: None,
43        }
44    }
45}
46
47impl PostgresSequence {
48    pub fn get_create_statement(
49        &self,
50        schema: &PostgresSchema,
51        identifier_quoter: &IdentifierQuoter,
52    ) -> String {
53        let mut sql = String::new();
54        if self.is_internally_created {
55            sql.push_str("alter sequence ")
56        } else {
57            sql.push_str("create sequence ");
58        }
59
60        sql.push_str(&schema.name.quote(identifier_quoter, ColumnName));
61        sql.push('.');
62        sql.push_str(&self.name.quote(identifier_quoter, ColumnName));
63        sql.push_str(" as ");
64        sql.push_str(&self.data_type);
65        sql.push_str(" increment by ");
66        sql.push_str(&self.increment.to_string());
67        sql.push_str(" minvalue ");
68        sql.push_str(&self.min_value.to_string());
69        sql.push_str(" maxvalue ");
70        sql.push_str(&self.max_value.to_string());
71        sql.push_str(" start ");
72        sql.push_str(&self.start_value.to_string());
73        sql.push_str(" cache ");
74        sql.push_str(&self.cache_size.to_string());
75
76        if self.cycle {
77            sql.push_str(" cycle");
78        }
79
80        sql.push(';');
81
82        if let Some(comment) = &self.comment {
83            sql.push_str("\ncomment on sequence ");
84            sql.push_str(&schema.name.quote(identifier_quoter, ColumnName));
85            sql.push('.');
86            sql.push_str(&self.name.quote(identifier_quoter, ColumnName));
87            sql.push_str(" is ");
88            sql.push_str(&quote_value_string(comment));
89            sql.push(';');
90        }
91
92        sql
93    }
94
95    pub fn get_set_value_statement(
96        &self,
97        schema: &PostgresSchema,
98        identifier_quoter: &IdentifierQuoter,
99    ) -> Option<String> {
100        self.last_value.map(|last_value| {
101            format!(
102                "select pg_catalog.setval('{}.{}', {}, true);",
103                schema.name.quote(identifier_quoter, ColumnName),
104                self.name.quote(identifier_quoter, ColumnName),
105                last_value
106            )
107        })
108    }
109}
110
111impl Ord for PostgresSequence {
112    fn cmp(&self, other: &Self) -> Ordering {
113        self.name.cmp(&other.name)
114    }
115}
116
117impl PartialOrd for PostgresSequence {
118    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
119        Some(self.cmp(other))
120    }
121}