2013-09-02 20:54:02 +00:00
|
|
|
extern mod extra;
|
|
|
|
|
2013-09-08 20:27:15 +00:00
|
|
|
use extra::time::Timespec;
|
2013-09-02 20:54:02 +00:00
|
|
|
use extra::json;
|
|
|
|
use extra::json::Json;
|
|
|
|
use extra::uuid::Uuid;
|
2013-08-31 23:11:42 +00:00
|
|
|
use std::rt::io::Decorator;
|
2013-09-02 19:42:24 +00:00
|
|
|
use std::rt::io::extensions::{WriterByteConversions, ReaderByteConversions};
|
2013-09-04 02:35:28 +00:00
|
|
|
use std::rt::io::mem::{MemWriter, BufReader};
|
2013-08-28 04:36:27 +00:00
|
|
|
use std::str;
|
|
|
|
|
2013-09-30 02:47:30 +00:00
|
|
|
/// A Postgres OID
|
2013-08-30 05:58:26 +00:00
|
|
|
pub type Oid = i32;
|
|
|
|
|
2013-08-30 06:28:46 +00:00
|
|
|
// Values from pg_type.h
|
|
|
|
static BOOLOID: Oid = 16;
|
2013-09-02 19:42:24 +00:00
|
|
|
static BYTEAOID: Oid = 17;
|
2013-09-02 22:14:22 +00:00
|
|
|
static CHAROID: Oid = 18;
|
2013-08-31 23:11:42 +00:00
|
|
|
static INT8OID: Oid = 20;
|
|
|
|
static INT2OID: Oid = 21;
|
|
|
|
static INT4OID: Oid = 23;
|
2013-09-02 20:07:57 +00:00
|
|
|
static TEXTOID: Oid = 25;
|
2013-09-02 20:54:02 +00:00
|
|
|
static JSONOID: Oid = 114;
|
2013-08-31 23:11:42 +00:00
|
|
|
static FLOAT4OID: Oid = 700;
|
|
|
|
static FLOAT8OID: Oid = 701;
|
2013-09-02 21:52:23 +00:00
|
|
|
static BPCHAROID: Oid = 1042;
|
2013-09-02 17:27:09 +00:00
|
|
|
static VARCHAROID: Oid = 1043;
|
2013-09-09 04:33:41 +00:00
|
|
|
static TIMESTAMPOID: Oid = 1114;
|
|
|
|
static TIMESTAMPZOID: Oid = 1184;
|
2013-09-02 20:54:02 +00:00
|
|
|
static UUIDOID: Oid = 2950;
|
2013-08-30 06:28:46 +00:00
|
|
|
|
2013-09-08 20:27:15 +00:00
|
|
|
static USEC_PER_SEC: i64 = 1_000_000;
|
|
|
|
static NSEC_PER_USEC: i64 = 1_000;
|
|
|
|
|
|
|
|
// Number of seconds from 1970-01-01 to 2000-01-01
|
|
|
|
static TIME_SEC_CONVERSION: i64 = 946684800;
|
|
|
|
|
2013-09-30 02:47:30 +00:00
|
|
|
/// A Postgres type
|
2013-09-05 04:51:21 +00:00
|
|
|
#[deriving(Eq)]
|
2013-09-05 04:26:43 +00:00
|
|
|
pub enum PostgresType {
|
2013-09-30 02:47:30 +00:00
|
|
|
/// BOOL
|
2013-09-05 04:26:43 +00:00
|
|
|
PgBool,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// BYTEA
|
2013-09-05 04:26:43 +00:00
|
|
|
PgByteA,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// "char"
|
2013-09-05 04:26:43 +00:00
|
|
|
PgChar,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// INT8/BIGINT
|
2013-09-05 04:26:43 +00:00
|
|
|
PgInt8,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// INT2/SMALLINT
|
2013-09-05 04:26:43 +00:00
|
|
|
PgInt2,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// INT4/INT
|
2013-09-05 04:26:43 +00:00
|
|
|
PgInt4,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// TEXT
|
2013-09-05 04:26:43 +00:00
|
|
|
PgText,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// JSON
|
2013-09-05 04:26:43 +00:00
|
|
|
PgJson,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// FLOAT4/REAL
|
2013-09-05 04:26:43 +00:00
|
|
|
PgFloat4,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// FLOAT8/DOUBLE PRECISION
|
2013-09-05 04:26:43 +00:00
|
|
|
PgFloat8,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// TIMESTAMP
|
2013-09-08 20:27:15 +00:00
|
|
|
PgTimestamp,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// TIMESTAMP WITH TIME ZONE
|
2013-09-09 04:33:41 +00:00
|
|
|
PgTimestampZ,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// CHAR(n)/CHARACTER(n)
|
2013-09-05 04:26:43 +00:00
|
|
|
PgCharN,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// VARCHAR/CHARACTER VARYING
|
2013-09-05 04:26:43 +00:00
|
|
|
PgVarchar,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// UUID
|
2013-09-05 04:26:43 +00:00
|
|
|
PgUuid,
|
2013-09-30 02:47:30 +00:00
|
|
|
/// An unknown type along with its OID
|
2013-09-05 04:26:43 +00:00
|
|
|
PgUnknownType(Oid)
|
2013-08-30 05:58:26 +00:00
|
|
|
}
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
impl PostgresType {
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Creates a PostgresType from a Postgres OID.
|
2013-09-05 04:26:43 +00:00
|
|
|
pub fn from_oid(oid: Oid) -> PostgresType {
|
|
|
|
match oid {
|
|
|
|
BOOLOID => PgBool,
|
|
|
|
BYTEAOID => PgByteA,
|
|
|
|
CHAROID => PgChar,
|
|
|
|
INT8OID => PgInt8,
|
|
|
|
INT2OID => PgInt2,
|
|
|
|
INT4OID => PgInt4,
|
|
|
|
TEXTOID => PgText,
|
|
|
|
JSONOID => PgJson,
|
|
|
|
FLOAT4OID => PgFloat4,
|
|
|
|
FLOAT8OID => PgFloat8,
|
2013-09-08 20:27:15 +00:00
|
|
|
TIMESTAMPOID => PgTimestamp,
|
2013-09-09 04:33:41 +00:00
|
|
|
TIMESTAMPZOID => PgTimestampZ,
|
2013-09-05 04:26:43 +00:00
|
|
|
BPCHAROID => PgCharN,
|
|
|
|
VARCHAROID => PgVarchar,
|
|
|
|
UUIDOID => PgUuid,
|
|
|
|
oid => PgUnknownType(oid)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Returns the wire format needed for the value of `self`.
|
2013-09-05 04:26:43 +00:00
|
|
|
pub fn result_format(&self) -> Format {
|
|
|
|
match *self {
|
2013-09-16 02:43:46 +00:00
|
|
|
PgUnknownType(*) => Text,
|
|
|
|
_ => Binary
|
2013-09-05 04:26:43 +00:00
|
|
|
}
|
2013-09-02 19:42:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-30 02:47:30 +00:00
|
|
|
/// The wire format of a Postgres value
|
2013-09-05 04:26:43 +00:00
|
|
|
pub enum Format {
|
2013-10-04 05:13:58 +00:00
|
|
|
/// A user-readable string format
|
2013-09-05 04:26:43 +00:00
|
|
|
Text = 0,
|
2013-10-04 05:13:58 +00:00
|
|
|
/// A machine-readable binary format
|
2013-09-05 04:26:43 +00:00
|
|
|
Binary = 1
|
|
|
|
}
|
|
|
|
|
2013-09-05 04:30:20 +00:00
|
|
|
macro_rules! check_types(
|
|
|
|
($($expected:pat)|+, $actual:ident) => (
|
2013-09-02 20:07:57 +00:00
|
|
|
match $actual {
|
|
|
|
$($expected)|+ => (),
|
2013-09-05 04:30:20 +00:00
|
|
|
actual => fail2!("Invalid Postgres type {:?}", actual)
|
2013-09-02 19:42:24 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-09-30 05:22:10 +00:00
|
|
|
/// A trait for types that can be created from a Postgres value
|
2013-08-28 04:36:27 +00:00
|
|
|
pub trait FromSql {
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Creates a new value of this type from a buffer of Postgres data.
|
|
|
|
///
|
|
|
|
/// If the value was `NULL`, the buffer will be `None`.
|
|
|
|
///
|
2013-10-13 06:19:57 +00:00
|
|
|
/// # Failure
|
|
|
|
///
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Fails if this type can not be created from the provided Postgres type.
|
2013-09-05 04:26:43 +00:00
|
|
|
fn from_sql(ty: PostgresType, raw: &Option<~[u8]>) -> Self;
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
|
2013-09-02 21:06:22 +00:00
|
|
|
macro_rules! from_map_impl(
|
2013-09-05 04:30:20 +00:00
|
|
|
($($expected:pat)|+, $t:ty, $blk:expr) => (
|
2013-08-28 04:36:27 +00:00
|
|
|
impl FromSql for Option<$t> {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn from_sql(ty: PostgresType, raw: &Option<~[u8]>) -> Option<$t> {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!($($expected)|+, ty)
|
2013-10-11 03:50:39 +00:00
|
|
|
raw.as_ref().map($blk)
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-09-02 21:06:22 +00:00
|
|
|
macro_rules! from_conversions_impl(
|
2013-09-05 04:30:20 +00:00
|
|
|
($expected:pat, $t:ty, $f:ident) => (
|
|
|
|
from_map_impl!($expected, $t, |buf| {
|
2013-09-04 02:35:28 +00:00
|
|
|
let mut reader = BufReader::new(buf.as_slice());
|
2013-09-02 21:06:22 +00:00
|
|
|
reader.$f()
|
|
|
|
})
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-08-28 04:36:27 +00:00
|
|
|
macro_rules! from_option_impl(
|
|
|
|
($t:ty) => (
|
|
|
|
impl FromSql for $t {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn from_sql(ty: PostgresType, raw: &Option<~[u8]>) -> $t {
|
2013-08-28 04:36:27 +00:00
|
|
|
// FIXME when you can specify Self types properly
|
2013-09-02 19:42:24 +00:00
|
|
|
let ret: Option<$t> = FromSql::from_sql(ty, raw);
|
2013-08-28 04:36:27 +00:00
|
|
|
ret.unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
from_map_impl!(PgBool, bool, |buf| { buf[0] != 0 })
|
2013-08-30 06:28:46 +00:00
|
|
|
from_option_impl!(bool)
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgChar, i8, read_i8_)
|
2013-09-02 22:14:22 +00:00
|
|
|
from_option_impl!(i8)
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgInt2, i16, read_be_i16_)
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(i16)
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgInt4, i32, read_be_i32_)
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(i32)
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgInt8, i64, read_be_i64_)
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(i64)
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgFloat4, f32, read_be_f32_)
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(f32)
|
2013-09-05 04:26:43 +00:00
|
|
|
from_conversions_impl!(PgFloat8, f64, read_be_f64_)
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(f64)
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
from_map_impl!(PgVarchar | PgText | PgCharN, ~str, |buf| {
|
2013-09-07 18:28:26 +00:00
|
|
|
str::from_utf8(buf.as_slice())
|
2013-09-02 21:06:22 +00:00
|
|
|
})
|
2013-08-28 04:36:27 +00:00
|
|
|
from_option_impl!(~str)
|
|
|
|
|
2013-09-02 19:42:24 +00:00
|
|
|
impl FromSql for Option<~[u8]> {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn from_sql(ty: PostgresType, raw: &Option<~[u8]>) -> Option<~[u8]> {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgByteA, ty)
|
2013-09-02 19:42:24 +00:00
|
|
|
raw.clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
from_option_impl!(~[u8])
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
from_map_impl!(PgJson, Json, |buf| {
|
2013-09-07 18:28:26 +00:00
|
|
|
json::from_str(str::from_utf8_slice(buf.as_slice())).unwrap()
|
2013-09-02 21:06:22 +00:00
|
|
|
})
|
2013-09-02 20:54:02 +00:00
|
|
|
from_option_impl!(Json)
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
from_map_impl!(PgUuid, Uuid, |buf| {
|
2013-09-07 22:45:11 +00:00
|
|
|
Uuid::from_bytes(buf.as_slice()).unwrap()
|
2013-09-02 21:06:22 +00:00
|
|
|
})
|
2013-09-02 20:54:02 +00:00
|
|
|
from_option_impl!(Uuid)
|
|
|
|
|
2013-09-09 04:33:41 +00:00
|
|
|
from_map_impl!(PgTimestamp | PgTimestampZ, Timespec, |buf| {
|
2013-09-08 20:27:15 +00:00
|
|
|
let mut rdr = BufReader::new(buf.as_slice());
|
|
|
|
let t = rdr.read_be_i64_();
|
|
|
|
let mut sec = t / USEC_PER_SEC + TIME_SEC_CONVERSION;
|
|
|
|
let mut usec = t % USEC_PER_SEC;
|
|
|
|
|
|
|
|
if usec < 0 {
|
|
|
|
sec -= 1;
|
|
|
|
usec = USEC_PER_SEC + usec;
|
|
|
|
}
|
|
|
|
|
|
|
|
Timespec::new(sec, (usec * NSEC_PER_USEC) as i32)
|
|
|
|
})
|
|
|
|
from_option_impl!(Timespec)
|
|
|
|
|
2013-09-30 02:47:30 +00:00
|
|
|
/// A trait for types that can be converted into Postgres values
|
2013-08-28 04:36:27 +00:00
|
|
|
pub trait ToSql {
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Converts the value of `self` into a format appropriate for the Postgres
|
|
|
|
/// backend.
|
|
|
|
///
|
2013-10-13 06:19:57 +00:00
|
|
|
/// # Failure
|
|
|
|
///
|
2013-09-30 02:47:30 +00:00
|
|
|
/// Fails if this type cannot be converted into the specified Postgres
|
|
|
|
/// type.
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>);
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! to_option_impl(
|
2013-09-02 20:07:57 +00:00
|
|
|
($($oid:ident)|+, $t:ty) => (
|
2013-08-28 04:36:27 +00:00
|
|
|
impl ToSql for Option<$t> {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!($($oid)|+, ty)
|
2013-09-02 17:27:09 +00:00
|
|
|
|
2013-08-30 05:58:26 +00:00
|
|
|
match *self {
|
|
|
|
None => (Text, None),
|
2013-09-02 17:27:09 +00:00
|
|
|
Some(ref val) => val.to_sql(ty)
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-02 20:54:02 +00:00
|
|
|
);
|
|
|
|
(self, $($oid:ident)|+, $t:ty) => (
|
|
|
|
impl<'self> ToSql for Option<$t> {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!($($oid)|+, ty)
|
2013-09-02 20:54:02 +00:00
|
|
|
|
|
|
|
match *self {
|
|
|
|
None => (Text, None),
|
|
|
|
Some(ref val) => val.to_sql(ty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-28 04:36:27 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-08-31 23:11:42 +00:00
|
|
|
macro_rules! to_conversions_impl(
|
2013-09-02 20:07:57 +00:00
|
|
|
($($oid:ident)|+, $t:ty, $f:ident) => (
|
2013-08-31 23:11:42 +00:00
|
|
|
impl ToSql for $t {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!($($oid)|+, ty)
|
2013-09-02 17:27:09 +00:00
|
|
|
|
|
|
|
let mut writer = MemWriter::new();
|
|
|
|
writer.$f(*self);
|
|
|
|
(Binary, Some(writer.inner()))
|
2013-08-31 23:11:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2013-08-30 06:28:46 +00:00
|
|
|
impl ToSql for bool {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgBool, ty)
|
2013-09-02 17:27:09 +00:00
|
|
|
(Binary, Some(~[*self as u8]))
|
2013-08-30 06:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
2013-09-05 04:26:43 +00:00
|
|
|
to_option_impl!(PgBool, bool)
|
|
|
|
|
|
|
|
to_conversions_impl!(PgChar, i8, write_i8_)
|
|
|
|
to_option_impl!(PgChar, i8)
|
|
|
|
to_conversions_impl!(PgInt2, i16, write_be_i16_)
|
|
|
|
to_option_impl!(PgInt2, i16)
|
|
|
|
to_conversions_impl!(PgInt4, i32, write_be_i32_)
|
|
|
|
to_option_impl!(PgInt4, i32)
|
|
|
|
to_conversions_impl!(PgInt8, i64, write_be_i64_)
|
|
|
|
to_option_impl!(PgInt8, i64)
|
|
|
|
to_conversions_impl!(PgFloat4, f32, write_be_f32_)
|
|
|
|
to_option_impl!(PgFloat4, f32)
|
|
|
|
to_conversions_impl!(PgFloat8, f64, write_be_f64_)
|
|
|
|
to_option_impl!(PgFloat8, f64)
|
2013-08-28 04:36:27 +00:00
|
|
|
|
2013-09-03 06:19:03 +00:00
|
|
|
impl ToSql for ~str {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgVarchar | PgText | PgCharN, ty)
|
2013-09-03 06:19:03 +00:00
|
|
|
(Text, Some(self.as_bytes().to_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-28 04:36:27 +00:00
|
|
|
impl<'self> ToSql for &'self str {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgVarchar | PgText | PgCharN, ty)
|
2013-08-30 05:58:26 +00:00
|
|
|
(Text, Some(self.as_bytes().to_owned()))
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
to_option_impl!(PgVarchar | PgText | PgCharN, ~str)
|
|
|
|
to_option_impl!(self, PgVarchar | PgText | PgCharN, &'self str)
|
2013-09-02 19:42:24 +00:00
|
|
|
|
2013-09-03 06:19:03 +00:00
|
|
|
impl ToSql for ~[u8] {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgByteA, ty)
|
2013-09-03 06:19:03 +00:00
|
|
|
(Binary, Some(self.to_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-02 19:42:24 +00:00
|
|
|
impl<'self> ToSql for &'self [u8] {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgByteA, ty)
|
2013-09-02 19:42:24 +00:00
|
|
|
(Binary, Some(self.to_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
to_option_impl!(PgByteA, ~[u8])
|
|
|
|
to_option_impl!(self, PgByteA, &'self [u8])
|
2013-09-02 19:42:24 +00:00
|
|
|
|
2013-09-02 20:54:02 +00:00
|
|
|
impl ToSql for Json {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgJson, ty)
|
2013-09-02 20:54:02 +00:00
|
|
|
(Text, Some(self.to_str().into_bytes()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
to_option_impl!(PgJson, Json)
|
2013-09-02 20:54:02 +00:00
|
|
|
|
|
|
|
impl ToSql for Uuid {
|
2013-09-05 04:26:43 +00:00
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-05 04:30:20 +00:00
|
|
|
check_types!(PgUuid, ty)
|
2013-09-02 20:54:02 +00:00
|
|
|
(Binary, Some(self.to_bytes().to_owned()))
|
2013-09-02 19:42:24 +00:00
|
|
|
}
|
|
|
|
}
|
2013-09-02 20:54:02 +00:00
|
|
|
|
2013-09-05 04:26:43 +00:00
|
|
|
to_option_impl!(PgUuid, Uuid)
|
2013-09-08 20:27:15 +00:00
|
|
|
|
|
|
|
impl ToSql for Timespec {
|
|
|
|
fn to_sql(&self, ty: PostgresType) -> (Format, Option<~[u8]>) {
|
2013-09-09 04:33:41 +00:00
|
|
|
check_types!(PgTimestamp | PgTimestampZ, ty)
|
2013-09-08 20:27:15 +00:00
|
|
|
let t = (self.sec - TIME_SEC_CONVERSION) * USEC_PER_SEC
|
|
|
|
+ self.nsec as i64 / NSEC_PER_USEC;
|
|
|
|
let mut buf = MemWriter::new();
|
|
|
|
buf.write_be_i64_(t);
|
|
|
|
(Binary, Some(buf.inner()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-09 04:33:41 +00:00
|
|
|
to_option_impl!(PgTimestamp | PgTimestampZ, Timespec)
|