mysql: Add JSON support

This commit is contained in:
Peter Maatman
2020-04-01 11:33:31 +02:00
committed by Ryan Leckey
parent 57f52ffbc4
commit 30d13174ea
4 changed files with 101 additions and 2 deletions

View File

@@ -0,0 +1,58 @@
use crate::decode::Decode;
use crate::encode::Encode;
use crate::mysql::database::MySql;
use crate::mysql::protocol::TypeId;
use crate::mysql::types::*;
use crate::mysql::{MySqlTypeInfo, MySqlValue};
use crate::types::{Json, Type};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
impl Type<MySql> for JsonValue {
fn type_info() -> MySqlTypeInfo {
<Json<Self> as Type<MySql>>::type_info()
}
}
impl Encode<MySql> for JsonValue {
fn encode(&self, buf: &mut Vec<u8>) {
(Box::new(Json(self)) as Box<dyn Encode<MySql>>).encode(buf)
}
}
impl<'de> Decode<'de, MySql> for JsonValue {
fn decode(value: MySqlValue<'de>) -> crate::Result<Self> {
<Json<Self> as Decode<MySql>>::decode(value).map(|item| item.0)
}
}
impl<T> Type<MySql> for Json<T> {
fn type_info() -> MySqlTypeInfo {
// MySql uses the CHAR type to pass JSON data from and to the client
MySqlTypeInfo::new(TypeId::CHAR)
}
}
impl<T> Encode<MySql> for Json<T>
where
T: Serialize,
{
fn encode(&self, buf: &mut Vec<u8>) {
let json_string_value =
serde_json::to_string(&self.0).expect("serde_json failed to convert to string");
<str as Encode<MySql>>::encode(json_string_value.as_str(), buf);
}
}
impl<'de, T> Decode<'de, MySql> for Json<T>
where
T: 'de,
T: for<'de1> Deserialize<'de1>,
{
fn decode(value: MySqlValue<'de>) -> crate::Result<Self> {
let string_value = <&'de str as Decode<MySql>>::decode(value).unwrap();
serde_json::from_str(&string_value)
.map(Json)
.map_err(crate::Error::decode)
}
}

View File

@@ -47,6 +47,13 @@
//! | Rust type | MySQL type(s) |
//! |---------------------------------------|------------------------------------------------------|
//! | `bigdecimal::BigDecimal` | DECIMAL |
//! ### [`json`](https://crates.io/crates/json)
//!
//! Requires the `json` Cargo feature flag.
//!
//! | Rust type | MySQL type(s) |
//! |---------------------------------------|------------------------------------------------------|
//! | `json::JsonValue` | JSON
//!
//! # Nullable
//!
@@ -70,6 +77,9 @@ mod chrono;
#[cfg(feature = "time")]
mod time;
#[cfg(feature = "json")]
mod json;
use crate::decode::Decode;
use crate::mysql::{MySql, MySqlValue};

View File

@@ -23,7 +23,7 @@ impl Type<Postgres> for JsonValue {
impl Encode<Postgres> for JsonValue {
fn encode(&self, buf: &mut PgRawBuffer) {
Json(self).encode(buf)
(Box::new(Json(self)) as Box<dyn Encode<Postgres>>).encode(buf)
}
}
@@ -41,7 +41,7 @@ impl Type<Postgres> for &'_ JsonRawValue {
impl Encode<Postgres> for &'_ JsonRawValue {
fn encode(&self, buf: &mut PgRawBuffer) {
Json(self).encode(buf)
(Box::new(Json(self)) as Box<dyn Encode<Postgres>>).encode(buf)
}
}