1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::sql_entity_graph::mapping::RustSqlMapping;
use crate::sql_entity_graph::pgx_sql::PgxSql;
use crate::sql_entity_graph::to_sql::entity::ToSqlConfigEntity;
use crate::sql_entity_graph::to_sql::ToSql;
use crate::sql_entity_graph::{SqlGraphEntity, SqlGraphIdentifier};
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PostgresEnumEntity {
pub name: &'static str,
pub file: &'static str,
pub line: u32,
pub full_path: &'static str,
pub module_path: &'static str,
pub mappings: std::collections::HashSet<RustSqlMapping>,
pub variants: Vec<&'static str>,
pub to_sql_config: ToSqlConfigEntity,
}
impl Hash for PostgresEnumEntity {
fn hash<H: Hasher>(&self, state: &mut H) {
self.full_path.hash(state);
}
}
impl Ord for PostgresEnumEntity {
fn cmp(&self, other: &Self) -> Ordering {
self.file.cmp(other.file).then_with(|| self.file.cmp(other.file))
}
}
impl PartialOrd for PostgresEnumEntity {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PostgresEnumEntity {
pub fn id_matches(&self, candidate: &core::any::TypeId) -> bool {
self.mappings.iter().any(|tester| *candidate == tester.id)
}
}
impl From<PostgresEnumEntity> for SqlGraphEntity {
fn from(val: PostgresEnumEntity) -> Self {
SqlGraphEntity::Enum(val)
}
}
impl SqlGraphIdentifier for PostgresEnumEntity {
fn dot_identifier(&self) -> String {
format!("enum {}", self.full_path)
}
fn rust_identifier(&self) -> String {
self.full_path.to_string()
}
fn file(&self) -> Option<&'static str> {
Some(self.file)
}
fn line(&self) -> Option<u32> {
Some(self.line)
}
}
impl ToSql for PostgresEnumEntity {
#[tracing::instrument(level = "debug", err, skip(self, context), fields(identifier = %self.rust_identifier()))]
fn to_sql(&self, context: &PgxSql) -> eyre::Result<String> {
let self_index = context.enums[self];
let sql = format!(
"\n\
-- {file}:{line}\n\
-- {full_path}\n\
CREATE TYPE {schema}{name} AS ENUM (\n\
{variants}\
);\
",
schema = context.schema_prefix_for(&self_index),
full_path = self.full_path,
file = self.file,
line = self.line,
name = self.name,
variants = self
.variants
.iter()
.map(|variant| format!("\t'{}'", variant))
.collect::<Vec<_>>()
.join(",\n")
+ "\n",
);
tracing::trace!(%sql);
Ok(sql)
}
}