rbatis_core/mysql/
sqlx_value.rs1use rbson::{Binary, Bson, to_bson};
2use sqlx_core::column::Column;
3use sqlx_core::decode::Decode;
4use sqlx_core::error::BoxDynError;
5use sqlx_core::mysql::{MySql, MySqlRow, MySqlValue, MySqlValueRef};
6use sqlx_core::row::Row;
7use sqlx_core::type_info::TypeInfo;
8use sqlx_core::types::{BigDecimal, Json};
9use sqlx_core::value::ValueRef;
10
11use crate::convert::{JsonCodec, RefJsonCodec, ResultCodec};
12use chrono::{DateTime, Utc, NaiveDate};
13
14use crate::{to_bson_macro};
15use rbson::bson;
16use rbson::spec::BinarySubtype;
17use crate::db::db_adapter::DataDecoder;
18
19
20impl<'r> JsonCodec for sqlx_core::mysql::MySqlValueRef<'r> {
21 fn try_to_bson(self) -> crate::Result<Bson> {
22 match self.type_info().name() {
23 "NULL" => {
24 return Ok(Bson::Null);
25 }
26 "DECIMAL" => {
27 let r: Option<String> = Decode::<'_, MySql>::decode(self)?;
28 if let Some(date) = r {
29 return Ok(Bson::String(date));
30 }
31 return Ok(Bson::Null);
32 }
33 "BIGINT UNSIGNED" => {
34 let r: Option<u64> = Decode::<'_, MySql>::decode(self)?;
35 if let Some(r) = r {
36 return Ok(bson!(r));
37 }
38 return Ok(Bson::Null);
39 }
40 "BIGINT" => {
41 let r: Option<i64> = Decode::<'_, MySql>::decode(self)?;
42 return Ok(to_bson_macro!(r));
43 }
44 "INT UNSIGNED" | "MEDIUMINT UNSIGNED" => {
45 let r: Option<u32> = Decode::<'_, MySql>::decode(self)?;
46 return Ok(to_bson_macro!(r));
47 }
48 "INT" | "MEDIUMINT" => {
49 let r: Option<i32> = Decode::<'_, MySql>::decode(self)?;
50 return Ok(to_bson_macro!(r));
51 }
52 "SMALLINT" => {
53 let r: Option<i16> = Decode::<'_, MySql>::decode(self)?;
54 if let Some(r) = r {
55 return Ok(bson!(r as i32));
56 }
57 return Ok(Bson::Null);
58 }
59 "SMALLINT UNSIGNED" => {
60 let r: Option<u16> = Decode::<'_, MySql>::decode(self)?;
61 if let Some(r) = r {
62 return Ok(bson!(r as u32));
63 }
64 return Ok(Bson::Null);
65 }
66 "TINYINT UNSIGNED" => {
67 let r: Option<u8> = Decode::<'_, MySql>::decode(self)?;
68 if let Some(r) = r {
69 return Ok(bson!(r as u32));
70 }
71 return Ok(Bson::Null);
72 }
73 "TINYINT" => {
74 let r: Option<i8> = Decode::<'_, MySql>::decode(self)?;
75 if let Some(r) = r {
76 return Ok(bson!(r as i32));
77 }
78 return Ok(Bson::Null);
79 }
80 "FLOAT" => {
81 let r: Option<f32> = Decode::<'_, MySql>::decode(self)?;
82 return Ok(to_bson_macro!(r));
83 }
84 "DOUBLE" => {
85 let r: Option<f64> = Decode::<'_, MySql>::decode(self)?;
86 return Ok(to_bson_macro!(r));
87 }
88 "BINARY" | "VARBINARY" | "CHAR" | "VARCHAR" | "TEXT" | "ENUM" => {
89 let r: Option<String> = Decode::<'_, MySql>::decode(self)?;
90 return Ok(to_bson_macro!(r));
91 }
92 "BLOB" | "TINYBLOB" | "MEDIUMBLOB" | "LONGBLOB" | "TINYTEXT" | "MEDIUMTEXT"
93 | "LONGTEXT" => {
94 let r: Option<Vec<u8>> = Decode::<'_, MySql>::decode(self)?;
95 if let Some(r) = r {
96 return Ok(Bson::Binary(rbson::Binary {
97 subtype: BinarySubtype::Generic,
98 bytes: r,
99 }));
100 }
101 return Ok(Bson::Null);
102 }
103 "BIT" => {
104 let r: Option<u8> = Decode::<'_, MySql>::decode(self)?;
105 if let Some(r) = r {
106 return Ok(bson!(r as i32));
107 }
108 return Ok(Bson::Null);
109 }
110 "BOOLEAN" => {
111 let r: Option<u8> = Decode::<'_, MySql>::decode(self)?;
112 if let Some(r) = r {
113 let mut b = false;
114 if r == 1 {
115 b = true;
116 }
117 return Ok(bson!(b));
118 }
119 return Ok(Bson::Null);
120 }
121 "DATE" => {
122 let r: Option<chrono::NaiveDate> = Decode::<'_, MySql>::decode(self)?;
123 return Ok(to_bson(&r).unwrap_or_default());
124 }
125 "TIME" | "YEAR" => {
126 let r: Option<chrono::NaiveTime> = Decode::<'_, MySql>::decode(self)?;
127 return Ok(to_bson(&r).unwrap_or_default());
128 }
129 "DATETIME" => {
130 let r: Option<chrono::NaiveDateTime> = Decode::<'_, MySql>::decode(self)?;
131 if let Some(dt) = r {
132 return Ok(Bson::String(dt.format("%Y-%m-%dT%H:%M:%S").to_string()));
133 }
134 return Ok(Bson::Null);
135 }
136 "TIMESTAMP" => {
137 let r: Option<chrono::NaiveDateTime> = Decode::<'_, MySql>::decode(self)?;
138 if let Some(dt) = r {
139 return Ok(Bson::String(dt.format("%Y-%m-%dT%H:%M:%S").to_string()));
140 }
141 return Ok(Bson::Null);
142 }
143 "JSON" => {
144 let r: Option<Json<serde_json::Value>> = Decode::<'_, MySql>::decode(self)?;
145 if let Some(r) = r {
146 return Ok(to_bson(&r.0).unwrap_or_default());
147 }
148 return Ok(Bson::Null);
149 }
150 _ => {
151 let r: Option<Vec<u8>> = Decode::<'_, MySql>::decode(self)?;
153 if let Some(r) = r {
154 return Ok(Bson::Binary(rbson::Binary {
155 subtype: BinarySubtype::Generic,
156 bytes: r,
157 }));
158 }
159 return Ok(Bson::Null);
160 }
161 }
162 }
163}
164
165impl RefJsonCodec for Vec<MySqlRow> {
166 fn try_to_bson(&self, decoder: &dyn DataDecoder) -> crate::Result<rbson::Bson> {
167 let mut arr = Vec::with_capacity(self.len());
168 for row in self {
169 let mut m = rbson::Document::new();
170 let columns = row.columns();
171 for x in columns {
172 let key = x.name();
173 let v: MySqlValueRef = row.try_get_raw(key)?;
174 let mut bson = v.try_to_bson()?;
175 decoder.decode(key, &mut bson)?;
176 m.insert(key.to_owned(), bson);
177 }
178 arr.push(rbson::Bson::Document(m));
179 }
180 Ok(Bson::Array(arr))
181 }
182}