Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP moving mysql types.rs file to shared area #1905

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
warnings,
missing_debug_implementations,
missing_copy_implementations,
missing_docs
//missing_docs
)]
// Clippy lints
#![allow(
Expand Down Expand Up @@ -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")]
Expand Down
25 changes: 2 additions & 23 deletions diesel/src/mysql/backend.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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 {}
6 changes: 3 additions & 3 deletions diesel/src/mysql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
103 changes: 1 addition & 102 deletions diesel/src/mysql/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TinyInt, Mysql> for i8 {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
out.write_i8(*self).map(|_| IsNull::No).map_err(Into::into)
}
}

impl FromSql<TinyInt, Mysql> for i8 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
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>(ST);

impl ToSql<Unsigned<TinyInt>, Mysql> for u8 {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
ToSql::<TinyInt, Mysql>::to_sql(&(*self as i8), out)
}
}

impl FromSql<Unsigned<TinyInt>, Mysql> for u8 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i8 = FromSql::<TinyInt, Mysql>::from_sql(bytes)?;
Ok(signed as u8)
}
}

impl ToSql<Unsigned<SmallInt>, Mysql> for u16 {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
ToSql::<SmallInt, Mysql>::to_sql(&(*self as i16), out)
}
}

impl FromSql<Unsigned<SmallInt>, Mysql> for u16 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i16 = FromSql::<SmallInt, Mysql>::from_sql(bytes)?;
Ok(signed as u16)
}
}

impl ToSql<Unsigned<Integer>, Mysql> for u32 {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
ToSql::<Integer, Mysql>::to_sql(&(*self as i32), out)
}
}

impl FromSql<Unsigned<Integer>, Mysql> for u32 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i32 = FromSql::<Integer, Mysql>::from_sql(bytes)?;
Ok(signed as u32)
}
}

impl ToSql<Unsigned<BigInt>, Mysql> for u64 {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
ToSql::<BigInt, Mysql>::to_sql(&(*self as i64), out)
}
}

impl FromSql<Unsigned<BigInt>, Mysql> for u64 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i64 = FromSql::<BigInt, Mysql>::from_sql(bytes)?;
Ok(signed as u64)
}
}

impl ToSql<Bool, Mysql> for bool {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
let int_value = if *self { 1 } else { 0 };
<i32 as ToSql<Integer, Mysql>>::to_sql(&int_value, out)
}
}

impl FromSql<Bool, Mysql> for bool {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
Ok(not_none!(bytes).iter().any(|x| *x != 0))
}
}

impl<ST> HasSqlType<Unsigned<ST>> for Mysql
where
Mysql: HasSqlType<ST>,
{
fn metadata(lookup: &()) -> MysqlType {
<Mysql as HasSqlType<ST>>::metadata(lookup)
}

fn is_signed() -> IsSigned {
IsSigned::Unsigned
}
}
pub use mysql_like::types::Unsigned;

/// Represents the MySQL datetime type.
///
Expand Down
28 changes: 28 additions & 0 deletions diesel/src/mysql_like/backend.rs
Original file line number Diff line number Diff line change
@@ -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<DB: MysqlLikeBackend> Backend for DB {
type QueryBuilder = MysqlQueryBuilder;
type BindCollector = MysqlBindCollector;
type ByteOrder = NativeEndian;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust is so cool. I'm surprised this self referential trait relationship even compiled


impl<'a, DB: MysqlLikeBackend> HasRawValue<'a> for DB {
type RawValue = &'a [u8];
}

impl<DB: MysqlLikeBackend> TypeMetadata for DB {
type TypeMetadata = MysqlType;
type MetadataLookup = ();
}

impl<DB: MysqlLikeBackend> SupportsDefaultKeyword for DB {}
impl<DB: MysqlLikeBackend> UsesAnsiSavepointSyntax for DB {}
4 changes: 4 additions & 0 deletions diesel/src/mysql_like/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod backend;
pub mod types;

pub use self::backend::MysqlLikeBackend;
103 changes: 103 additions & 0 deletions diesel/src/mysql_like/types/mod.rs
Original file line number Diff line number Diff line change
@@ -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<MysqlLike: MysqlLikeBackend> ToSql<TinyInt, MysqlLike> for i8 {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
out.write_i8(*self).map(|_| IsNull::No).map_err(Into::into)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<TinyInt, MysqlLike> for i8 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
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>(ST);

impl<MysqlLike: MysqlLikeBackend> ToSql<Unsigned<TinyInt>, MysqlLike> for u8 {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
ToSql::<TinyInt, MysqlLike>::to_sql(&(*self as i8), out)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<Unsigned<TinyInt>, MysqlLike> for u8 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i8 = FromSql::<TinyInt, MysqlLike>::from_sql(bytes)?;
Ok(signed as u8)
}
}

impl<MysqlLike: MysqlLikeBackend> ToSql<Unsigned<SmallInt>, MysqlLike> for u16 {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
ToSql::<SmallInt, MysqlLike>::to_sql(&(*self as i16), out)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<Unsigned<SmallInt>, MysqlLike> for u16 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i16 = FromSql::<SmallInt, MysqlLike>::from_sql(bytes)?;
Ok(signed as u16)
}
}

impl<MysqlLike: MysqlLikeBackend> ToSql<Unsigned<Integer>, MysqlLike> for u32 {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
ToSql::<Integer, MysqlLike>::to_sql(&(*self as i32), out)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<Unsigned<Integer>, MysqlLike> for u32 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i32 = FromSql::<Integer, MysqlLike>::from_sql(bytes)?;
Ok(signed as u32)
}
}

impl<MysqlLike: MysqlLikeBackend> ToSql<Unsigned<BigInt>, MysqlLike> for u64 {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
ToSql::<BigInt, MysqlLike>::to_sql(&(*self as i64), out)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<Unsigned<BigInt>, MysqlLike> for u64 {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let signed: i64 = FromSql::<BigInt, MysqlLike>::from_sql(bytes)?;
Ok(signed as u64)
}
}

impl<MysqlLike: MysqlLikeBackend> ToSql<Bool, MysqlLike> for bool {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
let int_value = if *self { 1 } else { 0 };
<i32 as ToSql<Integer, MysqlLike>>::to_sql(&int_value, out)
}
}

impl<MysqlLike: MysqlLikeBackend> FromSql<Bool, MysqlLike> for bool {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
Ok(not_none!(bytes).iter().any(|x| *x != 0))
}
}

impl<MysqlLike, ST> HasSqlType<Unsigned<ST>> for MysqlLike
where
MysqlLike: MysqlLikeBackend + HasSqlType<ST>,
{
fn metadata(lookup: &MysqlLike::MetadataLookup) -> <MysqlLike as TypeMetadata>::TypeMetadata {
<MysqlLike as HasSqlType<ST>>::metadata(lookup)
}

fn is_signed() -> IsSigned {
IsSigned::Unsigned
}
}