feat(mssql): setup type tests for MSSQL and add support for all the int types

This commit is contained in:
Ryan Leckey 2020-06-06 12:09:46 -07:00
parent 434bfaa76a
commit 2a272bdd59
5 changed files with 104 additions and 8 deletions

View file

@ -154,3 +154,8 @@ required-features = [ "postgres" ]
name = "mssql"
path = "tests/mssql/mssql.rs"
required-features = [ "mssql" ]
[[test]]
name = "mssql-types"
path = "tests/mssql/types.rs"
required-features = [ "mssql" ]

View file

@ -8,6 +8,54 @@ use crate::mssql::protocol::type_info::{DataType, TypeInfo};
use crate::mssql::{MsSql, MsSqlTypeInfo, MsSqlValueRef};
use crate::types::Type;
impl Type<MsSql> for i8 {
fn type_info() -> MsSqlTypeInfo {
MsSqlTypeInfo(TypeInfo::new(DataType::IntN, 1))
}
}
impl Encode<'_, MsSql> for i8 {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
buf.extend(&self.to_le_bytes());
IsNull::No
}
}
impl Decode<'_, MsSql> for i8 {
fn accepts(ty: &MsSqlTypeInfo) -> bool {
matches!(ty.0.ty, DataType::TinyInt | DataType::IntN) && ty.0.size == 1
}
fn decode(value: MsSqlValueRef<'_>) -> Result<Self, BoxDynError> {
Ok(value.as_bytes()?[0] as i8)
}
}
impl Type<MsSql> for i16 {
fn type_info() -> MsSqlTypeInfo {
MsSqlTypeInfo(TypeInfo::new(DataType::IntN, 2))
}
}
impl Encode<'_, MsSql> for i16 {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
buf.extend(&self.to_le_bytes());
IsNull::No
}
}
impl Decode<'_, MsSql> for i16 {
fn accepts(ty: &MsSqlTypeInfo) -> bool {
matches!(ty.0.ty, DataType::SmallInt | DataType::IntN) && ty.0.size == 2
}
fn decode(value: MsSqlValueRef<'_>) -> Result<Self, BoxDynError> {
Ok(LittleEndian::read_i16(value.as_bytes()?))
}
}
impl Type<MsSql> for i32 {
fn type_info() -> MsSqlTypeInfo {
MsSqlTypeInfo(TypeInfo::new(DataType::IntN, 4))
@ -31,3 +79,27 @@ impl Decode<'_, MsSql> for i32 {
Ok(LittleEndian::read_i32(value.as_bytes()?))
}
}
impl Type<MsSql> for i64 {
fn type_info() -> MsSqlTypeInfo {
MsSqlTypeInfo(TypeInfo::new(DataType::IntN, 8))
}
}
impl Encode<'_, MsSql> for i64 {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
buf.extend(&self.to_le_bytes());
IsNull::No
}
}
impl Decode<'_, MsSql> for i64 {
fn accepts(ty: &MsSqlTypeInfo) -> bool {
matches!(ty.0.ty, DataType::BigInt | DataType::IntN) && ty.0.size == 8
}
fn decode(value: MsSqlValueRef<'_>) -> Result<Self, BoxDynError> {
Ok(LittleEndian::read_i64(value.as_bytes()?))
}
}

View file

@ -71,13 +71,11 @@ impl PgConnection {
}
while self.pending_ready_for_query_count > 0 {
loop {
let message = self.stream.recv().await?;
let message = self.stream.recv().await?;
if let MessageFormat::ReadyForQuery = message.format {
self.handle_ready_for_query(message)?;
break;
}
if let MessageFormat::ReadyForQuery = message.format {
self.handle_ready_for_query(message)?;
break;
}
}

View file

@ -146,11 +146,11 @@ macro_rules! __test_prepared_type {
.fetch_one(&mut conn)
.await?;
let matches: bool = row.try_get(0)?;
let matches: i32 = row.try_get(0)?;
let returned: $ty = row.try_get(1)?;
let round_trip: $ty = row.try_get(2)?;
assert!(matches,
assert!(matches != 0,
"[1] DB value mismatch; given value: {:?}\n\
as returned: {:?}\n\
round-trip: {:?}",
@ -182,6 +182,13 @@ macro_rules! MySql_query_for_test_prepared_type {
};
}
#[macro_export]
macro_rules! MsSql_query_for_test_prepared_type {
() => {
"SELECT CASE WHEN {0} = @p1 THEN 1 ELSE 0 END, {0}, @p2"
};
}
#[macro_export]
macro_rules! Sqlite_query_for_test_prepared_type {
() => {

14
tests/mssql/types.rs Normal file
View file

@ -0,0 +1,14 @@
use sqlx::mssql::MsSql;
use sqlx_test::test_type;
test_type!(i8(
MsSql,
"CAST(5 AS TINYINT)" == 5_i8,
"CAST(0 AS TINYINT)" == 0_i8
));
test_type!(i16(MsSql, "CAST(21415 AS SMALLINT)" == 21415_i16));
test_type!(i32(MsSql, "CAST(2141512 AS INT)" == 2141512_i32));
test_type!(i64(MsSql, "CAST(32324324432 AS BIGINT)" == 32324324432_i64));