1use rustorm_dao::{value::Array, Value};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
5pub enum SqlType {
6 Bool,
7 Tinyint,
8 Smallint,
9 Int,
10 Bigint,
11
12 Real,
13 Float,
14 Double,
15 Numeric,
16
17 Tinyblob,
18 Mediumblob,
19 Blob,
20 Longblob,
21 Varbinary,
22
23 Char,
24 Varchar,
25 Tinytext,
26 Mediumtext,
27 Text,
28 Json,
29 TsVector,
30
31 Uuid,
32 Date,
33 Timestamp,
34 TimestampTz,
35
36 Time,
37 TimeTz,
38 Interval,
39
40 IpAddress,
41
42 Point,
43
44 Enum(String, Vec<String>),
46 Array(Box<SqlType>),
47}
48
49impl SqlType {
50 pub fn is_array_type(&self) -> bool {
51 match *self {
52 SqlType::Array(_) => true,
53 _ => false,
54 }
55 }
56
57 pub fn is_integer_type(&self) -> bool {
58 match *self {
59 SqlType::Int => true,
60 SqlType::Tinyint => true,
61 SqlType::Smallint => true,
62 SqlType::Bigint => true,
63 _ => false,
64 }
65 }
66
67 pub fn is_decimal_type(&self) -> bool {
68 match *self {
69 SqlType::Real => true,
70 SqlType::Float => true,
71 SqlType::Double => true,
72 SqlType::Numeric => true,
73 _ => false,
74 }
75 }
76
77 pub fn cast_as(&self) -> Option<SqlType> {
78 match *self {
79 SqlType::TsVector => Some(SqlType::Text),
80 _ => None,
81 }
82 }
83
84 pub fn name(&self) -> String {
85 match *self {
86 SqlType::Text => "text".into(),
87 SqlType::TsVector => "tsvector".into(),
88 SqlType::Array(ref ty) => match ty.as_ref() {
89 SqlType::Text => "text[]".into(),
90 _ => panic!("not yet dealt {:?}", self),
91 },
92 _ => panic!("not yet dealt {:?}", self),
93 }
94 }
95}
96
97#[derive(Debug, Serialize, PartialEq, Clone)]
98pub enum ArrayType {
99 Bool,
100 Tinyint,
101 Smallint,
102 Int,
103 Bigint,
104
105 Real,
106 Float,
107 Double,
108 Numeric,
109
110 Char,
111 Varchar,
112 Tinytext,
113 Mediumtext,
114 Text,
115
116 Uuid,
117 Date,
118 Timestamp,
119 TimestampTz,
120
121 Enum(String, Vec<String>),
122}
123
124trait HasType {
125 fn get_type(&self) -> Option<SqlType>;
126}
127
128impl HasType for Value {
129 fn get_type(&self) -> Option<SqlType> {
130 match self {
131 Value::Nil => None,
132 Value::Bool(_) => Some(SqlType::Bool),
133 Value::Tinyint(_) => Some(SqlType::Tinyint),
134 Value::Smallint(_) => Some(SqlType::Smallint),
135 Value::Int(_) => Some(SqlType::Int),
136 Value::Bigint(_) => Some(SqlType::Bigint),
137 Value::Float(_) => Some(SqlType::Float),
138 Value::Double(_) => Some(SqlType::Double),
139 Value::BigDecimal(_) => Some(SqlType::Numeric),
140 Value::Blob(_) => Some(SqlType::Blob),
141 Value::Char(_) => Some(SqlType::Char),
142 Value::Text(_) => Some(SqlType::Text),
143 Value::Json(_) => Some(SqlType::Json),
144 Value::Uuid(_) => Some(SqlType::Uuid),
145 Value::Date(_) => Some(SqlType::Date),
146 Value::Time(_) => Some(SqlType::Time),
147 Value::DateTime(_) => Some(SqlType::Timestamp),
148 Value::Timestamp(_) => Some(SqlType::Timestamp),
149 Value::Interval(_) => Some(SqlType::Interval),
150 Value::Point(_) => Some(SqlType::Point),
151 Value::Array(Array::Int(_)) => Some(SqlType::Array(Box::new(SqlType::Int))),
152 Value::Array(Array::Float(_)) => Some(SqlType::Array(Box::new(SqlType::Float))),
153 Value::Array(Array::Text(_)) => Some(SqlType::Array(Box::new(SqlType::Text))),
154 }
155 }
156}
157
158impl SqlType {
159 pub fn same_type(&self, value: &Value) -> bool {
160 if let Some(simple_type) = value.get_type() {
161 if simple_type == *self {
162 return true;
163 }
164 match (self, value) {
165 (SqlType::Varchar, Value::Text(_)) => true,
166 (SqlType::TimestampTz, Value::Timestamp(_)) => true,
167 (_, _) => false,
168 }
169 } else {
170 false
171 }
172 }
173}