rbdc_mysql/types/
value.rs

1use crate::io::MySqlBufMutExt;
2use crate::protocol::text::ColumnType;
3use crate::result_set::MySqlTypeInfo;
4use crate::types::decode::{
5    decode_date, decode_time, decode_timestamp, decode_year, f32_decode, f64_decode, int_decode,
6    uint_decode,
7};
8use crate::types::enums::Enum;
9use crate::types::json::{decode_json, encode_json};
10use crate::types::set::Set;
11use crate::types::year::Year;
12use crate::types::{Decode, Encode, TypeInfo};
13use crate::value::{MySqlValue};
14use rbdc::date::Date;
15use rbdc::datetime::DateTime;
16use rbdc::decimal::Decimal;
17use rbdc::timestamp::Timestamp;
18use rbdc::types::time::Time;
19use rbdc::uuid::Uuid;
20use rbdc::{Error, Json};
21use rbs::Value;
22use std::str::FromStr;
23
24impl TypeInfo for Value {
25    fn type_info(&self) -> MySqlTypeInfo {
26        match self {
27            Value::Null => MySqlTypeInfo::null(),
28            Value::Bool(_) => MySqlTypeInfo::from_type(ColumnType::Tiny),
29            Value::I32(_) => MySqlTypeInfo::from_type(ColumnType::Long),
30            Value::I64(_) => MySqlTypeInfo::from_type(ColumnType::LongLong),
31            Value::U32(_) => MySqlTypeInfo::from_type(ColumnType::Long),
32            Value::U64(_) => MySqlTypeInfo::from_type(ColumnType::LongLong),
33            Value::F32(_) => MySqlTypeInfo::from_type(ColumnType::Float),
34            Value::F64(_) => MySqlTypeInfo::from_type(ColumnType::Double),
35            Value::String(_) => MySqlTypeInfo::from_type(ColumnType::VarChar),
36            Value::Binary(_) => MySqlTypeInfo::from_type(ColumnType::Blob),
37            Value::Array(_) => MySqlTypeInfo::from_type(ColumnType::Json),
38            Value::Map(_) => MySqlTypeInfo::from_type(ColumnType::Json),
39            Value::Ext(ext_type, _) => {
40                match *ext_type {
41                    "Uuid" => MySqlTypeInfo::from_type(ColumnType::VarChar),
42                    //decimal = 12345678
43                    "Decimal" => MySqlTypeInfo::from_type(ColumnType::NewDecimal),
44                    //year = "1993"
45                    "Year" => MySqlTypeInfo::from_type(ColumnType::Year),
46                    //Date = "1993-02-06"
47                    "Date" => MySqlTypeInfo::from_type(ColumnType::Date),
48                    //RFC3339NanoTime = "15:04:05.999999999"
49                    "Time" => MySqlTypeInfo::from_type(ColumnType::Time),
50                    //RFC3339 = "2006-01-02 15:04:05.999999"
51                    "Timestamp" => {
52                        //datetime=5byte
53                        MySqlTypeInfo::from_type(ColumnType::Timestamp)
54                    }
55                    "DateTime" => MySqlTypeInfo::from_type(ColumnType::Datetime),
56                    "Json" => MySqlTypeInfo::from_type(ColumnType::Json),
57                    "Enum" => MySqlTypeInfo::from_type(ColumnType::Enum),
58                    "Set" => MySqlTypeInfo::from_type(ColumnType::Set),
59                    _ => MySqlTypeInfo::null(),
60                }
61            }
62        }
63    }
64}
65
66impl Encode for Value {
67    fn encode(self, buf: &mut Vec<u8>) -> Result<usize, Error> {
68        match self {
69            Value::Null => Ok(0),
70            Value::Bool(v) => {
71                buf.extend(&(v as i8).to_le_bytes());
72                Ok(1)
73            }
74            Value::I32(v) => {
75                buf.extend(v.to_le_bytes());
76                Ok(4)
77            }
78            Value::I64(v) => {
79                buf.extend(v.to_le_bytes());
80                Ok(8)
81            }
82            Value::U32(v) => {
83                buf.extend(v.to_le_bytes());
84                Ok(4)
85            }
86            Value::U64(v) => {
87                buf.extend(v.to_le_bytes());
88                Ok(8)
89            }
90            Value::F32(v) => {
91                let len = &v.to_le_bytes();
92                buf.extend(len);
93                Ok(len.len())
94            }
95            Value::F64(v) => {
96                let len = &v.to_le_bytes();
97                buf.extend(len);
98                Ok(len.len())
99            }
100            Value::String(v) => {
101                buf.put_str_lenenc(&v);
102                Ok(0)
103            }
104            Value::Binary(v) => {
105                buf.put_bytes_lenenc(v);
106                Ok(0)
107            }
108            Value::Array(v) => encode_json(Value::Array(v), buf),
109            Value::Map(v) => encode_json(Value::Map(v), buf),
110            Value::Ext(ext_type, v) => {
111                match ext_type {
112                    "Uuid" => {
113                        //uuid -> string
114                        Uuid(v.into_string().unwrap_or_default()).encode(buf)
115                    }
116                    //decimal = 12345678
117                    "Decimal" => Decimal::from_str(v.as_str().unwrap_or_default())
118                        .unwrap_or_default()
119                        .encode(buf),
120                    //year = "1993"
121                    "Year" => Year(v.as_u64().unwrap_or_default() as u16).encode(buf),
122                    //Date = "1993-02-06"
123                    "Date" => Date(
124                        fastdate::Date::from_str(&v.into_string().unwrap_or_default())
125                            .map_err(|e| Error::from(e.to_string()))?,
126                    )
127                    .encode(buf),
128                    //RFC3339NanoTime = "15:04:05.999999999"
129                    "Time" => Time(
130                        fastdate::Time::from_str(&v.into_string().unwrap_or_default())
131                            .map_err(|e| Error::from(e.to_string()))?,
132                    )
133                    .encode(buf),
134                    //RFC3339 = "2006-01-02 15:04:05.999999"
135                    "Timestamp" => Timestamp(v.as_i64().unwrap_or_default()).encode(buf),
136                    "DateTime" => DateTime(
137                        fastdate::DateTime::from_str(&v.into_string().unwrap_or_default())
138                            .map_err(|e| Error::from(e.to_string()))?,
139                    )
140                    .encode(buf),
141                    "Json" => {
142                        let json_str = v.into_string().unwrap_or_default();
143                        Json(json_str).encode(buf)
144                    }
145                    "Enum" => Enum(v.into_string().unwrap_or_default()).encode(buf),
146                    "Set" => Set(v.into_string().unwrap_or_default()).encode(buf),
147                    _ => {
148                        buf.put_bytes_lenenc(v.into_bytes().unwrap_or_default());
149                        Ok(0)
150                    }
151                }
152            }
153        }
154    }
155}
156
157impl Decode for Value {
158    fn decode(v: MySqlValue) -> Result<Self, Error>
159    where
160        Self: Sized,
161    {
162        let type_info = v.type_info().r#type;
163        Ok(match type_info {
164            ColumnType::Tiny => Value::I32(int_decode(v).unwrap_or_default() as i32),
165            ColumnType::Short => Value::I32(int_decode(v).unwrap_or_default() as i32),
166            ColumnType::Long => Value::I64(int_decode(v).unwrap_or_default()),
167            ColumnType::Float => Value::F32(f32_decode(v).unwrap_or_default()),
168            ColumnType::Double => Value::F64(f64_decode(v).unwrap_or_default()),
169            ColumnType::Null => Value::Null,
170            ColumnType::LongLong => Value::I64(int_decode(v).unwrap_or_default()),
171            ColumnType::Int24 => Value::I32(int_decode(v).unwrap_or_default() as i32),
172            ColumnType::VarChar => Value::String(v.as_str().unwrap_or_default().to_string()),
173            ColumnType::Bit => Value::U64(uint_decode(v).unwrap_or_default()),
174            ColumnType::TinyBlob => Value::Binary(v.as_bytes().unwrap_or_default().to_vec()),
175            ColumnType::MediumBlob => Value::Binary(v.as_bytes().unwrap_or_default().to_vec()),
176            ColumnType::LongBlob => Value::Binary(v.as_bytes().unwrap_or_default().to_vec()),
177            ColumnType::Blob => Value::Binary(v.as_bytes().unwrap_or_default().to_vec()),
178            ColumnType::VarString => Value::String(v.as_str().unwrap_or_default().to_string()),
179            ColumnType::String => Value::String(v.as_str().unwrap_or_default().to_string()),
180            ColumnType::Timestamp => Value::Ext(
181                "Timestamp",
182                Box::new(Value::U64({
183                    let s = decode_timestamp(v).unwrap_or_default();
184                    let date =
185                        fastdate::DateTime::from_str(&s).map_err(|e| Error::from(e.to_string()))?;
186                    date.unix_timestamp_millis() as u64
187                })),
188            ),
189            ColumnType::Decimal => Value::Ext(
190                "Decimal",
191                Box::new(Value::String(v.as_str().unwrap_or("0").to_string())),
192            ),
193            ColumnType::Date => Value::Ext(
194                "Date",
195                Box::new(Value::String(decode_date(v).unwrap_or_default())),
196            ),
197            ColumnType::Time => Value::Ext(
198                "Time",
199                Box::new(Value::String(decode_time(v).unwrap_or_default())),
200            ),
201            ColumnType::Datetime => Value::Ext(
202                "DateTime",
203                Box::new(Value::String(DateTime::decode(v)?.to_string())),
204            ),
205            ColumnType::Year => Value::Ext(
206                "Year",
207                Box::new(Value::String(decode_year(v).unwrap_or_default())),
208            ),
209            ColumnType::Json => decode_json(v)?,
210            ColumnType::NewDecimal => Value::Ext(
211                "Decimal",
212                Box::new(Value::String(v.as_str().unwrap_or("0").to_string())),
213            ),
214            ColumnType::Enum => Value::Ext(
215                "Enum",
216                Box::new(Value::String(v.as_str().unwrap_or("").to_string())),
217            ),
218            ColumnType::Set => Value::Ext(
219                "Set",
220                Box::new(Value::String(v.as_str().unwrap_or("").to_string())),
221            ),
222            //bytes ,see https://dev.mysql.com/doc/internals/en/x-protocol-messages-messages.html
223            ColumnType::Geometry => Value::Ext(
224                "Geometry",
225                Box::new(Value::Binary(v.as_bytes().unwrap_or_default().to_vec())),
226            ),
227        })
228    }
229}