postgresql_schema_upgrader/
options.rs

1/// SSL Mode for the PostgreSQL connection.
2#[cfg(feature = "tls")]
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
4pub enum SslMode {
5    #[default]
6    Disable,
7    Require,
8}
9
10/// Options for the PostgreSQL schema upgrader.
11#[derive(Debug, Clone, Default)]
12pub struct PostgresUpgraderOptions {
13    #[cfg(feature = "tls")]
14    pub(crate) ssl_mode: SslMode,
15    pub(crate) schema: Option<String>,
16    pub(crate) create_schema: bool,
17}
18
19impl PostgresUpgraderOptions {
20    /// Returns a new builder for `PostgresUpgraderOptions`.
21    pub fn builder() -> PostgresUpgraderOptionsBuilder {
22        PostgresUpgraderOptionsBuilder::default()
23    }
24
25    pub(crate) fn apply_schema_substitution(&self, sql: &str) -> String {
26        if let Some(schema) = &self.schema {
27            sql.replace("{{SCHEMA}}", schema)
28        } else {
29            sql.to_string()
30        }
31    }
32}
33
34/// A builder for `PostgresUpgraderOptions`.
35#[derive(Default)]
36pub struct PostgresUpgraderOptionsBuilder {
37    #[cfg(feature = "tls")]
38    ssl_mode: SslMode,
39    schema: Option<String>,
40    create_schema: bool,
41}
42
43impl PostgresUpgraderOptionsBuilder {
44    /// Sets the SSL mode for the connection.
45    #[cfg(feature = "tls")]
46    pub fn ssl_mode(mut self, ssl_mode: SslMode) -> Self {
47        self.ssl_mode = ssl_mode;
48        self
49    }
50
51    /// Sets the target schema for migrations.
52    pub fn schema(mut self, schema: impl Into<String>) -> Self {
53        self.schema = Some(schema.into());
54        self
55    }
56
57    /// Whether to create the schema if it does not exist.
58    pub fn create_schema(mut self, create: bool) -> Self {
59        self.create_schema = create;
60        self
61    }
62
63    /// Builds a `PostgresUpgraderOptions` instance.
64    pub fn build(self) -> PostgresUpgraderOptions {
65        PostgresUpgraderOptions {
66            #[cfg(feature = "tls")]
67            ssl_mode: self.ssl_mode,
68            schema: self.schema,
69            create_schema: self.create_schema,
70        }
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_builder_defaults() {
80        let options = PostgresUpgraderOptions::builder().build();
81        assert!(options.schema.is_none());
82        assert!(!options.create_schema);
83        #[cfg(feature = "tls")]
84        assert_eq!(options.ssl_mode, SslMode::Disable);
85    }
86
87    #[test]
88    fn test_builder_custom_values() {
89        let options = PostgresUpgraderOptions::builder()
90            .schema("my_schema")
91            .create_schema(true)
92            .build();
93
94        assert_eq!(options.schema.as_deref(), Some("my_schema"));
95        assert!(options.create_schema);
96    }
97
98    #[test]
99    fn test_apply_schema_substitution_no_schema() {
100        let options = PostgresUpgraderOptions::builder().build();
101        let sql = "CREATE TABLE {{SCHEMA}}.test (id INT)";
102        let result = options.apply_schema_substitution(sql);
103        // Should remain unchanged if no schema is provided (or we might want to fail/strip?
104        // Current impl returns as is, which is correct behavior for "no substitution").
105        assert_eq!(result, sql);
106    }
107
108    #[test]
109    fn test_apply_schema_substitution_with_schema() {
110        let options = PostgresUpgraderOptions::builder()
111            .schema("my_schema")
112            .build();
113        let sql = "CREATE TABLE {{SCHEMA}}.test (id INT)";
114        let result = options.apply_schema_substitution(sql);
115        assert_eq!(result, "CREATE TABLE my_schema.test (id INT)");
116    }
117
118    #[test]
119    fn test_apply_schema_substitution_multiple_occurrences() {
120        let options = PostgresUpgraderOptions::builder().schema("public").build();
121        let sql = "SELECT * FROM {{SCHEMA}}.users JOIN {{SCHEMA}}.posts ON ...";
122        let result = options.apply_schema_substitution(sql);
123        assert_eq!(
124            result,
125            "SELECT * FROM public.users JOIN public.posts ON ..."
126        );
127    }
128}