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" => MySqlTypeInfo::from_type(ColumnType::NewDecimal),
44 "Year" => MySqlTypeInfo::from_type(ColumnType::Year),
46 "Date" => MySqlTypeInfo::from_type(ColumnType::Date),
48 "Time" => MySqlTypeInfo::from_type(ColumnType::Time),
50 "Timestamp" => {
52 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(v.into_string().unwrap_or_default()).encode(buf)
115 }
116 "Decimal" => Decimal::from_str(v.as_str().unwrap_or_default())
118 .unwrap_or_default()
119 .encode(buf),
120 "Year" => Year(v.as_u64().unwrap_or_default() as u16).encode(buf),
122 "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 "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 "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 ColumnType::Geometry => Value::Ext(
224 "Geometry",
225 Box::new(Value::Binary(v.as_bytes().unwrap_or_default().to_vec())),
226 ),
227 })
228 }
229}