Skip to content

Commit

Permalink
add support for Json in mssql
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Aug 10, 2023
1 parent fc891b8 commit 5ace007
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions sqlx-core/src/mssql/types/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::mssql::protocol::type_info::{DataType, TypeInfo};
use crate::mssql::{Mssql, MssqlTypeInfo, MssqlValueRef};
use crate::types::Json;
use crate::types::Type;
use serde::{Deserialize, Serialize};

impl<T> Type<Mssql> for Json<T> {
fn type_info() -> MssqlTypeInfo {
MssqlTypeInfo(TypeInfo::new(DataType::BigVarBinary, 0))
}

fn compatible(ty: &MssqlTypeInfo) -> bool {
matches!(
ty.0.ty,
DataType::VarBinary
| DataType::Binary
| DataType::BigVarBinary
| DataType::BigBinary
| DataType::VarChar
| DataType::Char
| DataType::BigVarChar
| DataType::BigChar
)
}
}

impl<'q, T> Encode<'q, Mssql> for Json<T>
where
T: Serialize,
{
fn produces(&self) -> Option<MssqlTypeInfo> {
let size = 0xFF_FF;
return Some(MssqlTypeInfo(TypeInfo::new(DataType::BigVarBinary, size)));
}

fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
serde_json::to_writer(buf, self).unwrap();
IsNull::No
}
}

impl<'r, T: 'r> Decode<'r, Mssql> for Json<T>
where
T: Deserialize<'r>,
{
fn decode(value: MssqlValueRef<'r>) -> Result<Self, BoxDynError> {
let buf = value.as_bytes()?;
serde_json::from_slice(buf).map(Json).map_err(Into::into)
}
}
3 changes: 3 additions & 0 deletions sqlx-core/src/mssql/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ mod uint;
#[cfg(feature = "chrono")]
mod chrono;

#[cfg(feature = "json")]
mod json;

impl<'q, T: 'q + Encode<'q, Mssql>> Encode<'q, Mssql> for Option<T> {
fn encode(self, buf: &mut Vec<u8>) -> IsNull {
if let Some(v) = self {
Expand Down
11 changes: 11 additions & 0 deletions tests/mssql/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,14 @@ mod chrono {
"CAST('00:00' AS TIME)" == NaiveTime::default(),
));
}

#[cfg(feature = "json")]
mod json {
use super::*;
use serde_json::Value;
use sqlx_core::types::Json;

test_type!(json_value<Json<Value>>(Mssql,
r#"'123'"# == Json(Value::Number(123.into()))
));
}

0 comments on commit 5ace007

Please sign in to comment.