Skip to content

Commit

Permalink
WIP moving mysql types.rs file to shared area
Browse files Browse the repository at this point in the history
  • Loading branch information
virome committed Nov 6, 2018
1 parent 5dc7b73 commit f9a10fb
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 133 deletions.
6 changes: 5 additions & 1 deletion diesel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
)]
#![cfg_attr(feature = "unstable", feature(specialization, try_from))]
// Built-in Lints
#![deny(warnings, missing_debug_implementations, missing_copy_implementations, missing_docs)]
#![deny(warnings, missing_debug_implementations, missing_copy_implementations)]
// Clippy lints
#![cfg_attr(
feature = "cargo-clippy",
Expand Down Expand Up @@ -192,6 +192,10 @@ pub mod migration;
pub mod row;
pub mod types;


#[cfg(feature = "mysql")]
mod mysql_like;

#[cfg(feature = "mysql")]
pub mod mysql;
#[cfg(feature = "postgres")]
Expand Down
21 changes: 2 additions & 19 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,17 +41,5 @@ pub enum MysqlType {
Blob,
}

impl Backend for Mysql {
type QueryBuilder = MysqlQueryBuilder;
type BindCollector = MysqlBindCollector;
type RawValue = [u8];
type ByteOrder = NativeEndian;
}

impl TypeMetadata for Mysql {
type TypeMetadata = MysqlType;
type MetadataLookup = ();
}
impl MysqlLikeBackend for Mysql {}

impl SupportsDefaultKeyword for Mysql {}
impl UsesAnsiSavepointSyntax for Mysql {}
4 changes: 2 additions & 2 deletions diesel/src/mysql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
//! MySQL, you may need to work with this module directly.

mod backend;
mod bind_collector;
pub mod bind_collector;
mod connection;

mod query_builder;
pub mod query_builder;
pub mod types;

pub use self::backend::{Mysql, MysqlType};
Expand Down
104 changes: 0 additions & 104 deletions diesel/src/mysql/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,110 +2,6 @@

#[cfg(feature = "chrono")]
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
}
}

/// Represents the MySQL datetime type.
///
Expand Down
25 changes: 25 additions & 0 deletions diesel/src/mysql_like/backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! The MySQL backend
use byteorder::NativeEndian;

use mysql::bind_collector::MysqlBindCollector;
use mysql::query_builder::MysqlQueryBuilder;
use mysql::MysqlType;
use backend::*;
use sql_types::TypeMetadata;

pub trait MysqlLikeBackend: Backend<RawValue=[u8]> {}

impl<DB: MysqlLikeBackend> Backend for DB {
type QueryBuilder = MysqlQueryBuilder;
type BindCollector = MysqlBindCollector;
type RawValue = [u8];
type ByteOrder = NativeEndian;
}

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

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

mod backend;
pub mod types;

pub use self::backend::{MysqlLikeBackend};
105 changes: 105 additions & 0 deletions diesel/src/mysql_like/types/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//! MySQL specific types
mod numeric;

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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ pub mod bigdecimal {
use self::bigdecimal::BigDecimal;
use std::io::prelude::*;

use backend::Backend;
use deserialize::{self, FromSql};
use mysql::Mysql;
use mysql_like::MysqlLikeBackend;
use serialize::{self, IsNull, Output, ToSql};
use sql_types::{Binary, Numeric};

impl ToSql<Numeric, Mysql> for BigDecimal {
fn to_sql<W: Write>(&self, out: &mut Output<W, Mysql>) -> serialize::Result {
impl<MysqlLike: MysqlLikeBackend> ToSql<Numeric, MysqlLike> for BigDecimal {
fn to_sql<W: Write>(&self, out: &mut Output<W, MysqlLike>) -> serialize::Result {
write!(out, "{}", *self)
.map(|_| IsNull::No)
.map_err(|e| e.into())
}
}

impl FromSql<Numeric, Mysql> for BigDecimal {
fn from_sql(bytes: Option<&<Mysql as Backend>::RawValue>) -> deserialize::Result<Self> {
let bytes_ptr = <*const [u8] as FromSql<Binary, Mysql>>::from_sql(bytes)?;
impl<MysqlLike> FromSql<Numeric, MysqlLike> for BigDecimal
where MysqlLike: MysqlLikeBackend {
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
let bytes_ptr = <*const [u8] as FromSql<Binary, MysqlLike>>::from_sql(bytes)?;
let bytes = unsafe { &*bytes_ptr };
BigDecimal::parse_bytes(bytes, 10)
.ok_or_else(|| Box::from(format!("{:?} is not valid decimal number ", bytes)))
Expand Down
3 changes: 3 additions & 0 deletions diesel/src/sql_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ pub use pg::types::sql_types::*;
#[cfg(feature = "mysql")]
pub use mysql::types::*;

#[cfg(feature = "mysql")]
pub use mysql_like::types::*;

/// Indicates that a SQL type exists for a backend.
///
/// # Deriving
Expand Down

0 comments on commit f9a10fb

Please sign in to comment.