diff --git a/diesel/src/lib.rs b/diesel/src/lib.rs index b2b4135882e5..cce044e80aec 100644 --- a/diesel/src/lib.rs +++ b/diesel/src/lib.rs @@ -99,7 +99,7 @@ warnings, missing_debug_implementations, missing_copy_implementations, - missing_docs + //missing_docs )] // Clippy lints #![allow( @@ -166,6 +166,9 @@ pub mod sql_types; pub mod migration; pub mod row; +#[cfg(feature = "mysql")] +mod mysql_like; + #[cfg(feature = "mysql")] pub mod mysql; #[cfg(feature = "postgres")] diff --git a/diesel/src/mysql/backend.rs b/diesel/src/mysql/backend.rs index a8827c9a20b4..2b017a39d0ad 100644 --- a/diesel/src/mysql/backend.rs +++ b/diesel/src/mysql/backend.rs @@ -1,11 +1,6 @@ //! The MySQL backend -use byteorder::NativeEndian; - -use super::bind_collector::MysqlBindCollector; -use super::query_builder::MysqlQueryBuilder; -use backend::*; -use sql_types::TypeMetadata; +use mysql_like::MysqlLikeBackend; /// The MySQL backend #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -46,20 +41,4 @@ pub enum MysqlType { Blob, } -impl Backend for Mysql { - type QueryBuilder = MysqlQueryBuilder; - type BindCollector = MysqlBindCollector; - type ByteOrder = NativeEndian; -} - -impl<'a> HasRawValue<'a> for Mysql { - type RawValue = &'a [u8]; -} - -impl TypeMetadata for Mysql { - type TypeMetadata = MysqlType; - type MetadataLookup = (); -} - -impl SupportsDefaultKeyword for Mysql {} -impl UsesAnsiSavepointSyntax for Mysql {} +impl MysqlLikeBackend for Mysql {} diff --git a/diesel/src/mysql/mod.rs b/diesel/src/mysql/mod.rs index 745b584e018a..bed92dd0c9be 100644 --- a/diesel/src/mysql/mod.rs +++ b/diesel/src/mysql/mod.rs @@ -4,11 +4,11 @@ //! However, if you are writing code specifically to extend Diesel on //! MySQL, you may need to work with this module directly. -mod backend; -mod bind_collector; +pub mod backend; +pub mod bind_collector; mod connection; -mod query_builder; +pub mod query_builder; pub mod types; pub use self::backend::{Mysql, MysqlType}; diff --git a/diesel/src/mysql/types/mod.rs b/diesel/src/mysql/types/mod.rs index d684fee1b369..f39d11aa9a86 100644 --- a/diesel/src/mysql/types/mod.rs +++ b/diesel/src/mysql/types/mod.rs @@ -4,108 +4,7 @@ mod date_and_time; mod numeric; -use byteorder::WriteBytesExt; -use std::io::Write; - -use deserialize::{self, FromSql}; -use mysql::{Mysql, MysqlType}; -use serialize::{self, IsNull, Output, ToSql}; -use sql_types::*; - -impl ToSql for i8 { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - out.write_i8(*self).map(|_| IsNull::No).map_err(Into::into) - } -} - -impl FromSql for i8 { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let bytes = not_none!(bytes); - Ok(bytes[0] as i8) - } -} - -/// Represents the MySQL unsigned type. -#[derive(Debug, Clone, Copy, Default, SqlType, QueryId)] -pub struct Unsigned(ST); - -impl ToSql, Mysql> for u8 { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - ToSql::::to_sql(&(*self as i8), out) - } -} - -impl FromSql, Mysql> for u8 { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let signed: i8 = FromSql::::from_sql(bytes)?; - Ok(signed as u8) - } -} - -impl ToSql, Mysql> for u16 { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - ToSql::::to_sql(&(*self as i16), out) - } -} - -impl FromSql, Mysql> for u16 { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let signed: i16 = FromSql::::from_sql(bytes)?; - Ok(signed as u16) - } -} - -impl ToSql, Mysql> for u32 { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - ToSql::::to_sql(&(*self as i32), out) - } -} - -impl FromSql, Mysql> for u32 { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let signed: i32 = FromSql::::from_sql(bytes)?; - Ok(signed as u32) - } -} - -impl ToSql, Mysql> for u64 { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - ToSql::::to_sql(&(*self as i64), out) - } -} - -impl FromSql, Mysql> for u64 { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - let signed: i64 = FromSql::::from_sql(bytes)?; - Ok(signed as u64) - } -} - -impl ToSql for bool { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - let int_value = if *self { 1 } else { 0 }; - >::to_sql(&int_value, out) - } -} - -impl FromSql for bool { - fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { - Ok(not_none!(bytes).iter().any(|x| *x != 0)) - } -} - -impl HasSqlType> for Mysql -where - Mysql: HasSqlType, -{ - fn metadata(lookup: &()) -> MysqlType { - >::metadata(lookup) - } - - fn is_signed() -> IsSigned { - IsSigned::Unsigned - } -} +pub use mysql_like::types::Unsigned; /// Represents the MySQL datetime type. /// diff --git a/diesel/src/mysql_like/backend.rs b/diesel/src/mysql_like/backend.rs new file mode 100644 index 000000000000..798960b4467d --- /dev/null +++ b/diesel/src/mysql_like/backend.rs @@ -0,0 +1,28 @@ +//! The MySQL backend +use byteorder::NativeEndian; + +use backend::*; +use mysql::bind_collector::MysqlBindCollector; +use mysql::query_builder::MysqlQueryBuilder; +use mysql::MysqlType; +use sql_types::TypeMetadata; + +pub trait MysqlLikeBackend: Backend + for<'a> HasRawValue<'a, RawValue = &'a [u8]> {} + +impl Backend for DB { + type QueryBuilder = MysqlQueryBuilder; + type BindCollector = MysqlBindCollector; + type ByteOrder = NativeEndian; +} + +impl<'a, DB: MysqlLikeBackend> HasRawValue<'a> for DB { + type RawValue = &'a [u8]; +} + +impl TypeMetadata for DB { + type TypeMetadata = MysqlType; + type MetadataLookup = (); +} + +impl SupportsDefaultKeyword for DB {} +impl UsesAnsiSavepointSyntax for DB {} diff --git a/diesel/src/mysql_like/mod.rs b/diesel/src/mysql_like/mod.rs new file mode 100644 index 000000000000..0635f01791df --- /dev/null +++ b/diesel/src/mysql_like/mod.rs @@ -0,0 +1,4 @@ +mod backend; +pub mod types; + +pub use self::backend::MysqlLikeBackend; diff --git a/diesel/src/mysql_like/types/mod.rs b/diesel/src/mysql_like/types/mod.rs new file mode 100644 index 000000000000..5c15ca7e7e74 --- /dev/null +++ b/diesel/src/mysql_like/types/mod.rs @@ -0,0 +1,103 @@ +//! MySQL specific types +use byteorder::WriteBytesExt; +use std::io::Write; + +use deserialize::{self, FromSql}; +use mysql_like::MysqlLikeBackend; +use serialize::{self, IsNull, Output, ToSql}; +use sql_types::*; + +impl ToSql for i8 { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + out.write_i8(*self).map(|_| IsNull::No).map_err(Into::into) + } +} + +impl FromSql for i8 { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let bytes = not_none!(bytes); + Ok(bytes[0] as i8) + } +} + +/// Represents the MySQL unsigned type. +#[derive(Debug, Clone, Copy, Default, SqlType, QueryId)] +pub struct Unsigned(ST); + +impl ToSql, MysqlLike> for u8 { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + ToSql::::to_sql(&(*self as i8), out) + } +} + +impl FromSql, MysqlLike> for u8 { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let signed: i8 = FromSql::::from_sql(bytes)?; + Ok(signed as u8) + } +} + +impl ToSql, MysqlLike> for u16 { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + ToSql::::to_sql(&(*self as i16), out) + } +} + +impl FromSql, MysqlLike> for u16 { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let signed: i16 = FromSql::::from_sql(bytes)?; + Ok(signed as u16) + } +} + +impl ToSql, MysqlLike> for u32 { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + ToSql::::to_sql(&(*self as i32), out) + } +} + +impl FromSql, MysqlLike> for u32 { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let signed: i32 = FromSql::::from_sql(bytes)?; + Ok(signed as u32) + } +} + +impl ToSql, MysqlLike> for u64 { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + ToSql::::to_sql(&(*self as i64), out) + } +} + +impl FromSql, MysqlLike> for u64 { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let signed: i64 = FromSql::::from_sql(bytes)?; + Ok(signed as u64) + } +} + +impl ToSql for bool { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + let int_value = if *self { 1 } else { 0 }; + >::to_sql(&int_value, out) + } +} + +impl FromSql for bool { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + Ok(not_none!(bytes).iter().any(|x| *x != 0)) + } +} + +impl HasSqlType> for MysqlLike +where + MysqlLike: MysqlLikeBackend + HasSqlType, +{ + fn metadata(lookup: &MysqlLike::MetadataLookup) -> ::TypeMetadata { + >::metadata(lookup) + } + + fn is_signed() -> IsSigned { + IsSigned::Unsigned + } +}