session/
session_config.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16
17use common_macro::stack_trace_debug;
18use snafu::{Location, Snafu};
19use sql::ast::Value;
20
21#[derive(Snafu)]
22#[snafu(visibility(pub))]
23#[stack_trace_debug]
24pub enum Error {
25    #[snafu(display("Invalid value for parameter \"{}\": {}\nHint: {}", name, value, hint,))]
26    InvalidConfigValue {
27        name: String,
28        value: String,
29        hint: String,
30        #[snafu(implicit)]
31        location: Location,
32    },
33}
34
35#[derive(Clone, Copy, Debug, Default)]
36pub enum PGByteaOutputValue {
37    #[default]
38    HEX,
39    ESCAPE,
40}
41
42impl TryFrom<Value> for PGByteaOutputValue {
43    type Error = Error;
44
45    fn try_from(value: Value) -> Result<Self, Self::Error> {
46        match &value {
47            Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
48                match s.to_uppercase().as_str() {
49                    "ESCAPE" => Ok(PGByteaOutputValue::ESCAPE),
50                    "HEX" => Ok(PGByteaOutputValue::HEX),
51                    _ => InvalidConfigValueSnafu {
52                        name: "BYTEA_OUTPUT",
53                        value: value.to_string(),
54                        hint: "Available values: escape, hex",
55                    }
56                    .fail(),
57                }
58            }
59            _ => InvalidConfigValueSnafu {
60                name: "BYTEA_OUTPUT",
61                value: value.to_string(),
62                hint: "Available values: escape, hex",
63            }
64            .fail(),
65        }
66    }
67}
68
69// Refers to: https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-DATESTYLE
70#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
71pub enum PGDateOrder {
72    #[default]
73    MDY,
74    DMY,
75    YMD,
76}
77
78impl Display for PGDateOrder {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        match self {
81            PGDateOrder::MDY => write!(f, "MDY"),
82            PGDateOrder::DMY => write!(f, "DMY"),
83            PGDateOrder::YMD => write!(f, "YMD"),
84        }
85    }
86}
87
88impl TryFrom<&str> for PGDateOrder {
89    type Error = Error;
90
91    fn try_from(s: &str) -> Result<Self, Self::Error> {
92        match s.to_uppercase().as_str() {
93            "US" | "NONEURO" | "NONEUROPEAN" | "MDY" => Ok(PGDateOrder::MDY),
94            "EUROPEAN" | "EURO" | "DMY" => Ok(PGDateOrder::DMY),
95            "YMD" => Ok(PGDateOrder::YMD),
96            _ => InvalidConfigValueSnafu {
97                name: "DateStyle",
98                value: s,
99                hint: format!("Unrecognized key word: {}", s),
100            }
101            .fail(),
102        }
103    }
104}
105impl TryFrom<&Value> for PGDateOrder {
106    type Error = Error;
107
108    fn try_from(value: &Value) -> Result<Self, Self::Error> {
109        match value {
110            Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
111                Self::try_from(s.as_str())
112            }
113            _ => InvalidConfigValueSnafu {
114                name: "DateStyle",
115                value: value.to_string(),
116                hint: format!("Unrecognized key word: {}", value),
117            }
118            .fail(),
119        }
120    }
121}
122
123#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
124pub enum PGDateTimeStyle {
125    #[default]
126    ISO,
127    SQL,
128    Postgres,
129    German,
130}
131
132impl Display for PGDateTimeStyle {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        match self {
135            PGDateTimeStyle::ISO => write!(f, "ISO"),
136            PGDateTimeStyle::SQL => write!(f, "SQL"),
137            PGDateTimeStyle::Postgres => write!(f, "Postgres"),
138            PGDateTimeStyle::German => write!(f, "German"),
139        }
140    }
141}
142
143impl TryFrom<&str> for PGDateTimeStyle {
144    type Error = Error;
145
146    fn try_from(s: &str) -> Result<Self, Self::Error> {
147        match s.to_uppercase().as_str() {
148            "ISO" => Ok(PGDateTimeStyle::ISO),
149            "SQL" => Ok(PGDateTimeStyle::SQL),
150            "POSTGRES" => Ok(PGDateTimeStyle::Postgres),
151            "GERMAN" => Ok(PGDateTimeStyle::German),
152            _ => InvalidConfigValueSnafu {
153                name: "DateStyle",
154                value: s,
155                hint: format!("Unrecognized key word: {}", s),
156            }
157            .fail(),
158        }
159    }
160}
161
162impl TryFrom<&Value> for PGDateTimeStyle {
163    type Error = Error;
164
165    fn try_from(value: &Value) -> Result<Self, Self::Error> {
166        match value {
167            Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
168                Self::try_from(s.as_str())
169            }
170            _ => InvalidConfigValueSnafu {
171                name: "DateStyle",
172                value: value.to_string(),
173                hint: format!("Unrecognized key word: {}", value),
174            }
175            .fail(),
176        }
177    }
178}