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