Uuid support for MySQL (#536)

* feat: uuid decoder for mysql, patterned on postgres

* feat: Add uuid on mysql encoding

* fix: encode after converting to bytes

* fix: use the byte decoder on uuids

* fix: remove unused import

* feat: Adds mysql encoding/decoding support for Hyphenated uuid

* fix: uncommented feature flag line

* fix: unresolved import

* fix: use sqlx string type for binary uuid

Co-authored-by: Ian Hume <Humeian@me.com>
This commit is contained in:
Joshua Koudys 2020-07-26 22:45:06 -04:00 committed by GitHub
parent ec0e84d8ac
commit 05ffcb312d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 0 deletions

View File

@ -55,6 +55,15 @@
//! |---------------------------------------|------------------------------------------------------|
//! | `rust_decimal::Decimal` | DECIMAL |
//!
//! ### [`uuid`](https://crates.io/crates/uuid)
//!
//! Requires the `uuid` Cargo feature flag.
//!
//! | Rust type | MySQL type(s) |
//! |---------------------------------------|------------------------------------------------------|
//! | `uuid::Uuid` | BYTE(16), VARCHAR, CHAR, TEXT |
//! | `uuid::adapter::Hyphenated` | CHAR(36) |
//!
//! ### [`json`](https://crates.io/crates/json)
//!
//! Requires the `json` Cargo feature flag.
@ -88,5 +97,8 @@ mod chrono;
#[cfg(feature = "time")]
mod time;
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "json")]
mod json;

View File

@ -0,0 +1,58 @@
use uuid::{adapter::Hyphenated, Uuid};
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::mysql::io::MySqlBufMutExt;
use crate::mysql::protocol::text::{ColumnFlags, ColumnType};
use crate::mysql::{MySql, MySqlTypeInfo, MySqlValueRef};
use crate::types::Type;
impl Type<MySql> for Uuid {
fn type_info() -> MySqlTypeInfo {
MySqlTypeInfo::binary(ColumnType::String)
}
}
impl Encode<'_, MySql> for Uuid {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
buf.put_bytes_lenenc(self.as_bytes());
IsNull::No
}
}
impl Decode<'_, MySql> for Uuid {
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
// delegate to the &[u8] type to decode from MySQL
let bytes = <&[u8] as Decode<MySql>>::decode(value)?;
// construct a Uuid from the returned bytes
Uuid::from_slice(bytes).map_err(Into::into)
}
}
impl Type<MySql> for Hyphenated {
fn type_info() -> MySqlTypeInfo {
MySqlTypeInfo {
r#type: ColumnType::String, // CHAR
char_set: 224, // utf8mb4_unicode_ci
flags: ColumnFlags::empty(),
}
}
}
impl Encode<'_, MySql> for Hyphenated {
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull {
buf.put_str_lenenc(&self.to_string());
IsNull::No
}
}
impl Decode<'_, MySql> for Hyphenated {
fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> {
let uuid: Result<Uuid, BoxDynError> = Uuid::parse_str(value.as_str()?).map_err(Into::into);
Ok(uuid?.to_hyphenated())
}
}