1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
//! Types which represent a native SQL data type, and the conversions between
//! them and Rust primitives. Additional types can be added by other crates.
pub mod ops;
mod ord;
mod impls;

#[doc(hidden)]
pub mod structs {
    pub mod data_types {
        //! Structs to represent the primitive equivalent of SQL types where
        //! there is no existing Rust primitive, or where using it would be
        //! confusing (such as date and time types)
        pub use super::super::impls::date_and_time::{PgTimestamp, PgDate, PgTime, PgInterval};
        pub use super::super::impls::floats::PgNumeric;
    }
}

/// Marker trait for types which can be compared for ordering.
pub use self::ord::SqlOrd;

use row::Row;
use std::error::Error;
use std::io::Write;

#[derive(Clone, Copy, Default)] pub struct Bool;

pub type SmallSerial = SmallInt;
pub type Serial = Integer;
pub type BigSerial = BigInt;

#[derive(Clone, Copy, Default)] pub struct SmallInt;
#[doc(hidden)] pub type Int2 = SmallInt;
#[derive(Clone, Copy, Default)] pub struct Integer;
#[doc(hidden)] pub type Int4 = Integer;
#[derive(Clone, Copy, Default)] pub struct BigInt;
#[doc(hidden)] pub type Int8 = BigInt;

#[derive(Clone, Copy, Default)] pub struct Float;
#[doc(hidden)] pub type Float4 = Float;
#[derive(Clone, Copy, Default)] pub struct Double;
#[doc(hidden)] pub type Float8 = Double;
#[derive(Clone, Copy, Default)] pub struct Numeric;

#[derive(Clone, Copy, Default)] pub struct Oid;

#[derive(Clone, Copy, Default)] pub struct VarChar;
#[doc(hidden)] pub type Varchar = VarChar;
#[derive(Clone, Copy, Default)] pub struct Text;

#[derive(Clone, Copy, Default)] pub struct Binary;

#[derive(Clone, Copy, Default)] pub struct Date;
#[derive(Clone, Copy, Default)] pub struct Interval;
#[derive(Clone, Copy, Default)] pub struct Time;
#[derive(Clone, Copy, Default)] pub struct Timestamp;

#[derive(Clone, Copy, Default)] pub struct Nullable<T: NativeSqlType>(T);
#[derive(Clone, Copy, Default)] pub struct Array<T: NativeSqlType>(T);

pub trait NativeSqlType {
    fn oid(&self) -> u32;
    fn new() -> Self where Self: Sized;
}

/// How to deserialize a single field of a given type. The input will always be
/// the binary representation, not the text.
pub trait FromSql<A: NativeSqlType>: Sized {
    fn from_sql(bytes: Option<&[u8]>) -> Result<Self, Box<Error>>;
}

/// How to deserialize multiple fields, with a known type. This type is
/// implemented for tuples of various sizes.
pub trait FromSqlRow<A: NativeSqlType>: Sized {
    fn build_from_row<T: Row>(row: &mut T) -> Result<Self, Box<Error>>;
}

impl<A, T> FromSqlRow<A> for T where
    A: NativeSqlType,
    T: FromSql<A>,
{
    fn build_from_row<R: Row>(row: &mut R) -> Result<Self, Box<Error>> {
        Self::from_sql(row.take())
    }
}

#[derive(Debug, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    Yes,
    No,
}

/// Serializes a single value to be sent to the database. The output will be
/// included as a bind parameter, and is expected to be the binary format, not
/// text.
pub trait ToSql<A: NativeSqlType> {
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error>>;
}

impl<'a, A, T> ToSql<A> for &'a T where
    A: NativeSqlType,
    T: ToSql<A>,
{
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error>> {
        (*self).to_sql(out)
    }
}