Skip to main content

dinoco_engine/databases/postgresql/
dialect.rs

1use crate::{AdapterDialect, ColumnDefinition, ColumnType, DinocoValue};
2
3pub struct PostgresDialect;
4
5impl AdapterDialect for PostgresDialect {
6    fn bind_param(&self, index: usize) -> String {
7        format!("${}", index)
8    }
9
10    fn cast_numeric_for_division(&self, expr: &str) -> String {
11        format!("CAST({expr} AS DOUBLE PRECISION)")
12    }
13
14    fn bind_value(&self, index: usize, value: &DinocoValue) -> String {
15        match value {
16            DinocoValue::Enum(type_name, _) => {
17                format!("{}::{}", self.bind_param(index), self.identifier(type_name))
18            }
19            _ => self.bind_param(index),
20        }
21    }
22
23    fn identifier(&self, v: &str) -> String {
24        let escaped = v.replace('"', "\"\"");
25
26        format!("\"{}\"", escaped)
27    }
28
29    fn literal_string(&self, v: &str) -> String {
30        let escaped = v.replace('\'', "''");
31        format!("'{}'", escaped)
32    }
33
34    fn supports_native_enums(&self) -> bool {
35        true
36    }
37
38    fn supports_insert_returning(&self) -> bool {
39        true
40    }
41
42    fn column_type(&self, col: &ColumnDefinition, is_primary: bool, auto_increment: bool) -> String {
43        let mut base_type = match &col.col_type {
44            ColumnType::Integer => "BIGINT".to_string(),
45            ColumnType::Float => "DOUBLE PRECISION".to_string(),
46            ColumnType::Text => "TEXT".to_string(),
47            ColumnType::Boolean => "BOOLEAN".to_string(),
48            ColumnType::Json => "JSONB".to_string(),
49            ColumnType::DateTime => "TIMESTAMP".to_string(),
50            ColumnType::Date => "DATE".to_string(),
51            ColumnType::Bytes => "BYTEA".to_string(),
52
53            ColumnType::Enum(name) => self.identifier(name),
54            ColumnType::EnumInline(_) => "TEXT".into(),
55        };
56
57        if auto_increment {
58            base_type.push_str(" GENERATED ALWAYS AS IDENTITY");
59        }
60
61        if is_primary {
62            base_type.push_str(" PRIMARY KEY");
63        }
64
65        base_type
66    }
67}