Reduce some duplication in type parsing

This commit is contained in:
Ryan Leckey 2020-03-12 20:14:28 -07:00
parent 7ab07016da
commit 1a48cf3b2c
5 changed files with 41 additions and 61 deletions

View File

@ -110,16 +110,16 @@ impl<'c> Row<'c> {
if is_null {
values.push(None);
} else {
let size = match columns[column_idx] {
TypeId::TINY_INT => 1,
TypeId::SMALL_INT => 2,
TypeId::INT | TypeId::FLOAT => 4,
TypeId::BIG_INT | TypeId::DOUBLE => 8,
let (offset, size) = match columns[column_idx] {
TypeId::TINY_INT => (0, 1),
TypeId::SMALL_INT => (0, 2),
TypeId::INT | TypeId::FLOAT => (0, 4),
TypeId::BIG_INT | TypeId::DOUBLE => (0, 8),
TypeId::DATE => 5,
TypeId::TIME => 1 + buffer[index] as usize,
TypeId::DATE => (0, 5),
TypeId::TIME => (0, 1 + buffer[index] as usize),
TypeId::TIMESTAMP | TypeId::DATETIME => 1 + buffer[index] as usize,
TypeId::TIMESTAMP | TypeId::DATETIME => (0, 1 + buffer[index] as usize),
TypeId::TINY_BLOB
| TypeId::MEDIUM_BLOB
@ -129,7 +129,7 @@ impl<'c> Row<'c> {
| TypeId::VAR_CHAR => {
let (len_size, len) = get_lenenc(&buffer[index..]);
len_size + len.unwrap_or_default()
(len_size, len.unwrap_or_default())
}
id => {
@ -137,8 +137,8 @@ impl<'c> Row<'c> {
}
};
values.push(Some(index..(index + size)));
index += size;
values.push(Some((index + offset)..(index + offset + size)));
index += size + offset;
}
}

View File

@ -2,7 +2,7 @@ use byteorder::LittleEndian;
use crate::decode::Decode;
use crate::encode::Encode;
use crate::mysql::io::{BufExt, BufMutExt};
use crate::mysql::io::{BufMutExt};
use crate::mysql::protocol::TypeId;
use crate::mysql::types::MySqlTypeInfo;
use crate::mysql::{MySql, MySqlValue};
@ -41,16 +41,7 @@ impl Encode<MySql> for Vec<u8> {
impl<'de> Decode<'de, MySql> for Vec<u8> {
fn decode(value: Option<MySqlValue<'de>>) -> crate::Result<Self> {
match value.try_into()? {
MySqlValue::Binary(mut buf) => {
let len = buf
.get_uint_lenenc::<LittleEndian>()
.map_err(crate::Error::decode)?
.unwrap_or_default();
Ok((&buf[..(len as usize)]).to_vec())
}
MySqlValue::Text(s) => Ok(s.to_vec()),
MySqlValue::Binary(buf) | MySqlValue::Text(buf) => Ok(buf.to_vec()),
}
}
}
@ -58,16 +49,7 @@ impl<'de> Decode<'de, MySql> for Vec<u8> {
impl<'de> Decode<'de, MySql> for &'de [u8] {
fn decode(value: Option<MySqlValue<'de>>) -> crate::Result<Self> {
match value.try_into()? {
MySqlValue::Binary(mut buf) => {
let len = buf
.get_uint_lenenc::<LittleEndian>()
.map_err(crate::Error::decode)?
.unwrap_or_default();
Ok(&buf[..(len as usize)])
}
MySqlValue::Text(s) => Ok(s),
MySqlValue::Binary(buf) | MySqlValue::Text(buf) => Ok(buf),
}
}
}

View File

@ -4,7 +4,7 @@ use byteorder::LittleEndian;
use crate::decode::Decode;
use crate::encode::Encode;
use crate::mysql::io::{BufExt, BufMutExt};
use crate::mysql::io::{BufMutExt};
use crate::mysql::protocol::TypeId;
use crate::mysql::types::MySqlTypeInfo;
use crate::mysql::{MySql, MySqlValue};
@ -44,16 +44,9 @@ impl Encode<MySql> for String {
impl<'de> Decode<'de, MySql> for &'de str {
fn decode(value: Option<MySqlValue<'de>>) -> crate::Result<Self> {
match value.try_into()? {
MySqlValue::Binary(mut buf) => {
let len = buf
.get_uint_lenenc::<LittleEndian>()
.map_err(crate::Error::decode)?
.unwrap_or_default();
from_utf8(&buf[..(len as usize)]).map_err(crate::Error::decode)
MySqlValue::Binary(buf) | MySqlValue::Text(buf) => {
from_utf8(buf).map_err(crate::Error::decode)
}
MySqlValue::Text(s) => from_utf8(s).map_err(crate::Error::decode),
}
}
}

View File

@ -25,10 +25,10 @@ pub(crate) fn expand_derive_encode(input: DeriveInput) -> syn::Result<proc_macro
Ok(quote!(
impl #impl_generics sqlx::encode::Encode<DB> for #ident #ty_generics #where_clause {
fn encode(&self, buf: &mut std::vec::Vec<u8>) {
fn encode(&self, buf: &mut <DB as sqlx::Database>::RawBuffer) {
sqlx::encode::Encode::encode(&self.0, buf)
}
fn encode_nullable(&self, buf: &mut std::vec::Vec<u8>) -> sqlx::encode::IsNull {
fn encode_nullable(&self, buf: &mut <DB as sqlx::Database>::RawBuffer) -> sqlx::encode::IsNull {
sqlx::encode::Encode::encode_nullable(&self.0, buf)
}
fn size_hint(&self) -> usize {

View File

@ -4,31 +4,36 @@ use sqlx::encode::Encode;
#[derive(PartialEq, Debug, Encode, Decode)]
struct Foo(i32);
#[test]
#[cfg(feature = "mysql")]
fn encode_mysql() {
encode_with_db::<sqlx::MySql>();
}
#[test]
#[cfg(feature = "postgres")]
fn encode_postgres() {
encode_with_db::<sqlx::Postgres>();
}
#[allow(dead_code)]
fn encode_with_db<DB: sqlx::Database>()
where
Foo: Encode<DB>,
i32: Encode<DB>,
fn encode_with_postgres()
{
use sqlx_core::postgres::Postgres;
let example = Foo(0x1122_3344);
let mut encoded = Vec::new();
let mut encoded_orig = Vec::new();
Encode::<DB>::encode(&example, &mut encoded);
Encode::<DB>::encode(&example.0, &mut encoded_orig);
Encode::<Postgres>::encode(&example, &mut encoded);
Encode::<Postgres>::encode(&example.0, &mut encoded_orig);
assert_eq!(encoded, encoded_orig);
}
#[test]
#[cfg(feature = "mysql")]
fn encode_with_mysql()
{
use sqlx_core::mysql::MySql;
let example = Foo(0x1122_3344);
let mut encoded = Vec::new();
let mut encoded_orig = Vec::new();
Encode::<MySql>::encode(&example, &mut encoded);
Encode::<MySql>::encode(&example.0, &mut encoded_orig);
assert_eq!(encoded, encoded_orig);
}