rust-postgres/src/types/mod.rs

887 lines
28 KiB
Rust
Raw Normal View History

2013-10-20 21:34:50 +00:00
//! Traits dealing with Postgres data types
pub use self::slice::Slice;
2014-06-06 03:50:23 +00:00
use std::collections::HashMap;
2015-01-28 16:52:33 +00:00
use std::old_io::net::ip::IpAddr;
use std::fmt;
2014-11-01 23:12:05 +00:00
use Result;
use error::Error;
2015-02-19 05:04:44 +00:00
pub use ugh_privacy::Other;
macro_rules! accepts {
($($expected:pat),+) => (
fn accepts(ty: &::types::Type) -> bool {
match *ty {
$($expected)|+ => true,
_ => false
}
}
)
}
2014-12-19 18:43:42 +00:00
macro_rules! check_types {
2015-01-09 18:26:24 +00:00
($($expected:pat),+; $actual:ident) => (
2014-11-17 17:43:10 +00:00
match $actual {
$(&$expected)|+ => {}
actual => return Err(::Error::WrongType(actual.clone()))
2014-11-17 17:43:10 +00:00
}
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! raw_from_impl {
2014-11-17 17:43:10 +00:00
($t:ty, $f:ident) => (
impl RawFromSql for $t {
fn raw_from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<$t> {
2014-11-17 17:43:10 +00:00
Ok(try!(raw.$f()))
}
}
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! from_option_impl {
2015-01-09 18:26:24 +00:00
($t:ty) => {
2014-11-18 03:11:32 +00:00
impl ::types::FromSql for $t {
2014-12-23 02:45:09 +00:00
fn from_sql(ty: &Type, raw: Option<&[u8]>) -> Result<$t> {
2014-11-18 03:11:32 +00:00
use Error;
use types::FromSql;
2014-11-17 17:43:10 +00:00
// FIXME when you can specify Self types properly
let ret: Result<Option<$t>> = FromSql::from_sql(ty, raw);
match ret {
Ok(Some(val)) => Ok(val),
Ok(None) => Err(Error::WasNull),
2014-11-17 17:43:10 +00:00
Err(err) => Err(err)
}
}
}
}
2014-12-19 18:43:42 +00:00
}
2014-12-19 18:43:42 +00:00
macro_rules! from_map_impl {
2015-01-09 18:26:24 +00:00
($($expected:pat),+; $t:ty, $blk:expr) => (
impl ::types::FromSql for Option<$t> {
2014-12-23 02:45:09 +00:00
fn from_sql(ty: &Type, raw: Option<&[u8]>) -> Result<Option<$t>> {
2015-01-09 18:26:24 +00:00
check_types!($($expected),+; ty);
2014-12-23 02:45:09 +00:00
match raw {
Some(buf) => ($blk)(ty, buf).map(|ok| Some(ok)),
None => Ok(None)
}
}
}
2015-01-09 18:26:24 +00:00
from_option_impl!($t);
2014-11-17 17:43:10 +00:00
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! from_raw_from_impl {
2015-01-09 18:26:24 +00:00
($($expected:pat),+; $t:ty) => (
2015-02-06 16:56:23 +00:00
from_map_impl!($($expected),+; $t, |ty, mut buf: &[u8]| {
2014-11-18 03:11:32 +00:00
use types::RawFromSql;
RawFromSql::raw_from_sql(ty, &mut buf)
2015-01-09 18:26:24 +00:00
});
2014-11-17 17:43:10 +00:00
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! raw_to_impl {
2014-11-17 17:43:10 +00:00
($t:ty, $f:ident) => (
impl RawToSql for $t {
fn raw_to_sql<W: Writer>(&self, _: &Type, w: &mut W) -> Result<()> {
2014-11-17 17:43:10 +00:00
Ok(try!(w.$f(*self)))
}
}
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! to_option_impl {
2015-01-09 18:26:24 +00:00
($($oid:pat),+; $t:ty) => (
2014-11-18 03:11:32 +00:00
impl ::types::ToSql for Option<$t> {
2014-11-17 17:43:10 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2015-01-09 18:26:24 +00:00
check_types!($($oid),+; ty);
2014-11-17 17:43:10 +00:00
match *self {
None => Ok(None),
Some(ref val) => val.to_sql(ty)
}
}
}
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! to_option_impl_lifetime {
2015-01-09 18:26:24 +00:00
($($oid:pat),+; $t:ty) => (
2014-11-17 17:43:10 +00:00
impl<'a> ToSql for Option<$t> {
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2015-01-09 18:26:24 +00:00
check_types!($($oid),+; ty);
2014-11-17 17:43:10 +00:00
match *self {
None => Ok(None),
Some(ref val) => val.to_sql(ty)
}
}
}
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
2014-12-19 18:43:42 +00:00
macro_rules! to_raw_to_impl {
2015-01-09 18:26:24 +00:00
($($oid:pat),+; $t:ty) => (
2014-11-18 03:11:32 +00:00
impl ::types::ToSql for $t {
2014-11-17 17:43:10 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2015-01-09 18:26:24 +00:00
check_types!($($oid),+; ty);
2014-11-17 17:43:10 +00:00
2014-11-20 04:54:32 +00:00
let mut writer = vec![];
try!(self.raw_to_sql(ty, &mut writer));
2014-11-20 04:54:32 +00:00
Ok(Some(writer))
2014-11-17 17:43:10 +00:00
}
}
2015-01-09 18:26:24 +00:00
to_option_impl!($($oid),+; $t);
2014-11-17 17:43:10 +00:00
)
2014-12-19 18:43:42 +00:00
}
2014-11-17 17:43:10 +00:00
#[cfg(feature = "uuid")]
mod uuid;
2015-02-08 03:52:45 +00:00
#[cfg(feature = "time")]
2014-11-18 03:11:32 +00:00
mod time;
mod slice;
#[cfg(feature = "rustc-serialize")]
mod json;
2013-10-29 05:35:52 +00:00
2013-09-30 02:47:30 +00:00
/// A Postgres OID
2014-01-03 07:10:26 +00:00
pub type Oid = u32;
2015-02-14 20:46:18 +00:00
/// Represents the kind of a Postgres type.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Kind {
/// A simple type like `VARCHAR` or `INTEGER`.
Simple,
/// An array type along with the type of its elements.
Array(Type),
/// A range type along with the type of its elements.
Range(Type),
}
2015-02-19 05:04:44 +00:00
macro_rules! as_pat {
($p:pat) => ($p)
}
macro_rules! as_expr {
($e:expr) => ($e)
}
2014-12-19 18:43:42 +00:00
macro_rules! make_postgres_type {
2015-02-19 05:04:44 +00:00
($(#[$doc:meta] $oid:tt => $variant:ident: $kind:expr),+) => (
2013-12-08 03:34:48 +00:00
/// A Postgres type
2015-01-10 21:58:46 +00:00
#[derive(PartialEq, Eq, Clone)]
2014-11-04 05:29:16 +00:00
pub enum Type {
2013-12-08 03:34:48 +00:00
$(
2014-03-29 21:33:11 +00:00
#[$doc]
2013-12-08 03:34:48 +00:00
$variant,
)+
/// An unknown type
2015-02-19 05:04:44 +00:00
Other(Box<Other>),
}
2015-01-23 18:44:15 +00:00
impl fmt::Debug for Type {
2015-01-10 21:58:46 +00:00
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let s = match *self {
$(Type::$variant => stringify!($variant),)+
2015-02-19 05:04:44 +00:00
Type::Other(ref u) => return fmt::Debug::fmt(u, fmt),
2015-01-10 21:58:46 +00:00
};
fmt.write_str(s)
}
}
2014-11-04 05:29:16 +00:00
impl Type {
/// Creates a `Type` from an OID.
///
2015-01-22 06:11:43 +00:00
/// If the OID is unknown, `None` is returned.
pub fn from_oid(oid: Oid) -> Option<Type> {
2013-12-08 03:34:48 +00:00
match oid {
2015-02-19 05:04:44 +00:00
$(as_pat!($oid) => Some(Type::$variant),)+
2015-01-22 06:11:43 +00:00
_ => None
2013-12-08 03:34:48 +00:00
}
}
/// Returns the OID of the `Type`.
2013-12-08 19:44:37 +00:00
pub fn to_oid(&self) -> Oid {
match *self {
2015-02-19 05:04:44 +00:00
$(Type::$variant => as_expr!($oid),)+
Type::Other(ref u) => u.oid(),
2013-12-08 19:44:37 +00:00
}
}
2015-02-14 20:46:18 +00:00
/// The kind of this type
2015-02-18 07:49:11 +00:00
pub fn kind(&self) -> &Kind {
2013-12-08 19:44:37 +00:00
match *self {
$(
2015-02-18 07:49:11 +00:00
Type::$variant => {
const V: &'static Kind = &$kind;
V
}
2013-12-08 19:44:37 +00:00
)+
2015-02-19 05:04:44 +00:00
Type::Other(ref u) => u.kind(),
2013-12-08 19:44:37 +00:00
}
}
}
2013-12-08 03:34:48 +00:00
)
2014-12-19 18:43:42 +00:00
}
2013-12-08 03:34:48 +00:00
2015-02-19 05:04:44 +00:00
// Values from pg_type.h
2014-12-19 18:43:42 +00:00
make_postgres_type! {
2015-02-19 05:04:44 +00:00
#[doc="BOOL - boolean, 'true'/'false'"]
16 => Bool: Kind::Simple,
#[doc="BYTEA - variable-length string, binary values escaped"]
17 => ByteA: Kind::Simple,
#[doc="\"char\" - single character"]
18 => Char: Kind::Simple,
#[doc="NAME - 63-byte type for storing system identifiers"]
19 => Name: Kind::Simple,
#[doc="INT8/BIGINT - ~18 digit integer, 8-byte storage"]
20 => Int8: Kind::Simple,
#[doc="INT2/SMALLINT - -32 thousand to 32 thousand, 2-byte storage"]
21 => Int2: Kind::Simple,
#[doc="INT2VECTOR - array of int2, used in system tables"]
22 => Int2Vector: Kind::Array(Type::Int2),
#[doc="INT4/INT - -2 billion to 2 billion integer, 4-byte storage"]
23 => Int4: Kind::Simple,
#[doc="REGPROC - registered procedure"]
24 => Regproc: Kind::Simple,
#[doc="TEXT - variable-length string, no limit specified"]
25 => Text: Kind::Simple,
#[doc="OID - object identifier(oid), maximum 4 billion"]
26 => Oid: Kind::Simple,
#[doc="TID - (block, offset), physical location of tuple"]
27 => Tid: Kind::Simple,
#[doc="XID - transaction id"]
28 => Xid: Kind::Simple,
#[doc="CID - command identifier type, sequence in transaction id"]
29 => Cid: Kind::Simple,
#[doc="OIDVECTOR - array of oids, used in system tables"]
30 => OidVector: Kind::Array(Type::Oid),
#[doc="PG_TYPE"]
71 => PgType: Kind::Simple,
#[doc="PG_ATTRIBUTE"]
75 => PgAttribute: Kind::Simple,
#[doc="PG_PROC"]
81 => PgProc: Kind::Simple,
#[doc="PG_CLASS"]
83 => PgClass: Kind::Simple,
2013-12-08 03:34:48 +00:00
#[doc="JSON"]
2015-02-19 05:04:44 +00:00
114 => Json: Kind::Simple,
#[doc="XML - XML content"]
142 => Xml: Kind::Simple,
#[doc="XML[]"]
143 => XmlArray: Kind::Array(Type::Xml),
#[doc="PG_NODE_TREE - string representing an internal node tree"]
194 => PgNodeTree: Kind::Simple,
2013-12-09 00:00:33 +00:00
#[doc="JSON[]"]
2015-02-19 05:04:44 +00:00
199 => JsonArray: Kind::Array(Type::Json),
#[doc="SMGR - storage manager"]
210 => Smgr: Kind::Simple,
#[doc="POINT - geometric point '(x, y)'"]
600 => Point: Kind::Simple,
#[doc="LSEG - geometric line segment '(pt1,pt2)'"]
601 => Lseg: Kind::Simple,
#[doc="PATH - geometric path '(pt1,...)'"]
602 => Path: Kind::Simple,
#[doc="BOX - geometric box '(lower left,upper right)'"]
603 => Box: Kind::Simple,
#[doc="POLYGON - geometric polygon '(pt1,...)'"]
604 => Polygon: Kind::Simple,
#[doc="LINE - geometric line"]
628 => Line: Kind::Simple,
#[doc="LINE[]"]
629 => LineArray: Kind::Array(Type::Line),
#[doc="CIDR - network IP address/netmask, network address"]
650 => Cidr: Kind::Simple,
#[doc="CIDR[]"]
651 => CidrArray: Kind::Array(Type::Cidr),
#[doc="FLOAT4/REAL - single-precision floating point number, 4-byte storage"]
700 => Float4: Kind::Simple,
#[doc="FLOAT8/DOUBLE PRECISION - double-precision floating point number, 8-byte storage"]
701 => Float8: Kind::Simple,
#[doc="ABSTIME - absolute, limited-range date and time (Unix system time)"]
702 => Abstime: Kind::Simple,
#[doc="RELTIME - relative, limited-range date and time (Unix delta time)"]
703 => Reltime: Kind::Simple,
#[doc="TINTERVAL - (abstime,abstime), time interval"]
704 => Tinterval: Kind::Simple,
#[doc="UNKNOWN"]
705 => Unknown: Kind::Simple,
#[doc="CIRCLE - geometric circle '(center,radius)'"]
718 => Circle: Kind::Simple,
#[doc="CIRCLE[]"]
719 => CircleArray: Kind::Array(Type::Circle),
#[doc="MONEY - monetary amounts, $d,ddd.cc"]
790 => Money: Kind::Simple,
#[doc="MONEY[]"]
791 => MoneyArray: Kind::Array(Type::Money),
#[doc="MACADDR - XX:XX:XX:XX:XX:XX, MAC address"]
829 => Macaddr: Kind::Simple,
#[doc="INET - IP address/netmask, host address, netmask optional"]
869 => Inet: Kind::Simple,
2013-12-08 03:34:48 +00:00
#[doc="BOOL[]"]
2015-02-19 05:04:44 +00:00
1000 => BoolArray: Kind::Array(Type::Bool),
2013-12-08 03:34:48 +00:00
#[doc="BYTEA[]"]
2015-02-19 05:04:44 +00:00
1001 => ByteAArray: Kind::Array(Type::ByteA),
2013-12-08 03:34:48 +00:00
#[doc="\"char\"[]"]
2015-02-19 05:04:44 +00:00
1002 => CharArray: Kind::Array(Type::Char),
#[doc="NAME[]"]
2015-02-19 05:04:44 +00:00
1003 => NameArray: Kind::Array(Type::Name),
2013-12-08 03:34:48 +00:00
#[doc="INT2[]"]
2015-02-19 05:04:44 +00:00
1005 => Int2Array: Kind::Array(Type::Int2),
#[doc="INT2VECTOR[]"]
1006 => Int2VectorArray: Kind::Array(Type::Int2Vector),
2013-12-08 03:34:48 +00:00
#[doc="INT4[]"]
2015-02-19 05:04:44 +00:00
1007 => Int4Array: Kind::Array(Type::Int4),
#[doc="REGPROC[]"]
1008 => RegprocArray: Kind::Array(Type::Regproc),
2013-12-08 03:34:48 +00:00
#[doc="TEXT[]"]
2015-02-19 05:04:44 +00:00
1009 => TextArray: Kind::Array(Type::Text),
#[doc="TID[]"]
1010 => TidArray: Kind::Array(Type::Tid),
#[doc="XID[]"]
1011 => XidArray: Kind::Array(Type::Xid),
#[doc="CID[]"]
1012 => CidArray: Kind::Array(Type::Cid),
#[doc="OIDVECTOR[]"]
1013 => OidVectorArray: Kind::Array(Type::OidVector),
#[doc="BPCHAR[]"]
1014 => BpcharArray: Kind::Array(Type::Bpchar),
2013-12-08 21:58:41 +00:00
#[doc="VARCHAR[]"]
2015-02-19 05:04:44 +00:00
1015 => VarcharArray: Kind::Array(Type::Varchar),
2013-12-08 03:34:48 +00:00
#[doc="INT8[]"]
2015-02-19 05:04:44 +00:00
1016 => Int8Array: Kind::Array(Type::Int8),
#[doc="POINT[]"]
1017 => PointArray: Kind::Array(Type::Point),
#[doc="LSEG[]"]
1018 => LsegArray: Kind::Array(Type::Lseg),
#[doc="PATH[]"]
1019 => PathArray: Kind::Array(Type::Path),
#[doc="BOX[]"]
1020 => BoxArray: Kind::Array(Type::Box),
2013-12-08 03:34:48 +00:00
#[doc="FLOAT4[]"]
2015-02-19 05:04:44 +00:00
1021 => Float4Array: Kind::Array(Type::Float4),
2013-12-08 03:34:48 +00:00
#[doc="FLOAT8[]"]
2015-02-19 05:04:44 +00:00
1022 => Float8Array: Kind::Array(Type::Float8),
#[doc="ABSTIME[]"]
1023 => AbstimeArray: Kind::Array(Type::Abstime),
#[doc="RELTIME[]"]
1024 => ReltimeArray: Kind::Array(Type::Reltime),
#[doc="TINTERVAL[]"]
1025 => TintervalArray: Kind::Array(Type::Tinterval),
#[doc="POLYGON[]"]
1027 => PolygonArray: Kind::Array(Type::Polygon),
#[doc="OID[]"]
1028 => OidArray: Kind::Array(Type::Oid),
#[doc="ACLITEM - access control list"]
1033 => Aclitem: Kind::Simple,
#[doc="ACLITEM[]"]
1034 => AclitemArray: Kind::Array(Type::Aclitem),
#[doc="MACADDR[]"]
1040 => MacaddrArray: Kind::Array(Type::Macaddr),
#[doc="INET[]"]
1041 => InetArray: Kind::Array(Type::Inet),
#[doc="BPCHAR - char(length), blank-padded string, fixed storage length"]
1042 => Bpchar: Kind::Simple,
#[doc="VARCHAR - varchar(length), non-blank-padded string, variable storage length"]
1043 => Varchar: Kind::Simple,
#[doc="DATE - date"]
1082 => Date: Kind::Simple,
#[doc="TIME - time of day"]
1083 => Time: Kind::Simple,
#[doc="TIMESTAMP - date and time"]
1114 => Timestamp: Kind::Simple,
2013-12-08 22:04:26 +00:00
#[doc="TIMESTAMP[]"]
2015-02-19 05:04:44 +00:00
1115 => TimestampArray: Kind::Array(Type::Timestamp),
#[doc="DATE[]"]
1182 => DateArray: Kind::Array(Type::Date),
#[doc="TIME[]"]
1183 => TimeArray: Kind::Array(Type::Time),
#[doc="TIMESTAMPTZ - date and time with time zone"]
1184 => TimestampTZ: Kind::Simple,
#[doc="TIMESTAMPTZ[]"]
1185 => TimestampTZArray: Kind::Array(Type::TimestampTZ),
#[doc="INTERVAL - @ <number> <units>, time interval"]
1186 => Interval: Kind::Simple,
#[doc="INTERVAL[]"]
1187 => IntervalArray: Kind::Array(Type::Interval),
#[doc="NUMERIC[]"]
1231 => NumericArray: Kind::Array(Type::Numeric),
#[doc="CSTRING[]"]
1263 => CstringArray: Kind::Array(Type::Cstring),
#[doc="TIMETZ - time of day with time zone"]
1266 => Timetz: Kind::Simple,
#[doc="TIMETZ[]"]
1270 => TimetzArray: Kind::Array(Type::Timetz),
#[doc="BIT - fixed-length bit string"]
1560 => Bit: Kind::Simple,
#[doc="BIT[]"]
1561 => BitArray: Kind::Array(Type::Bit),
#[doc="VARBIT - variable-length bit string"]
1562 => Varbit: Kind::Simple,
#[doc="VARBIT[]"]
1563 => VarbitArray: Kind::Array(Type::Varbit),
#[doc="NUMERIC - numeric(precision, decimal), arbitrary precision number"]
1700 => Numeric: Kind::Simple,
#[doc="REFCURSOR - reference to cursor (portal name)"]
1790 => Refcursor: Kind::Simple,
#[doc="REFCURSOR[]"]
2201 => RefcursorArray: Kind::Array(Type::Refcursor),
#[doc="REGPROCEDURE - registered procedure (with args)"]
2202 => Regprocedure: Kind::Simple,
#[doc="REGOPER - registered operator"]
2203 => Regoper: Kind::Simple,
#[doc="REGOPERATOR - registered operator (with args)"]
2204 => Regoperator: Kind::Simple,
#[doc="REGCLASS - registered class"]
2205 => Regclass: Kind::Simple,
#[doc="REGTYPE - registered type"]
2206 => Regtype: Kind::Simple,
#[doc="REGPROCEDURE[]"]
2207 => RegprocedureArray: Kind::Array(Type::Regprocedure),
#[doc="REGOPER[]"]
2208 => RegoperArray: Kind::Array(Type::Regoper),
#[doc="REGOPERATOR[]"]
2209 => RegoperatorArray: Kind::Array(Type::Regoperator),
#[doc="REGCLASS[]"]
2210 => RegclassArray: Kind::Array(Type::Regclass),
#[doc="REGTYPE[]"]
2211 => RegtypeArray: Kind::Array(Type::Regtype),
#[doc="RECORD"]
2249 => Record: Kind::Simple,
#[doc="CSTRING"]
2275 => Cstring: Kind::Simple,
#[doc="ANY"]
2276 => Any: Kind::Simple,
#[doc="ANY[]"]
2277 => AnyArray: Kind::Array(Type::Any),
#[doc="VOID"]
2278 => Void: Kind::Simple,
#[doc="TRIGGER"]
2279 => Trigger: Kind::Simple,
#[doc="LANGUAGE_HANDLER"]
2280 => LanguageHandler: Kind::Simple,
#[doc="INTERNAL"]
2281 => Internal: Kind::Simple,
#[doc="OPAQUE"]
2282 => Opaque: Kind::Simple,
#[doc="ANYELEMENT"]
2283 => Anyelement: Kind::Simple,
#[doc="RECORD[]"]
2287 => RecordArray: Kind::Array(Type::Record),
#[doc="ANYNONARRAY"]
2776 => Anynonarray: Kind::Simple,
#[doc="TXID_SNAPSHOT[]"]
2949 => TxidSnapshotArray: Kind::Array(Type::TxidSnapshot),
#[doc="UUID - UUID datatype"]
2950 => Uuid: Kind::Simple,
#[doc="TXID_SNAPSHOT - txid snapshot"]
2970 => TxidSnapshot: Kind::Simple,
2014-11-06 15:53:16 +00:00
#[doc="UUID[]"]
2015-02-19 05:04:44 +00:00
2951 => UuidArray: Kind::Array(Type::Uuid),
#[doc="FDW_HANDLER"]
3115 => FdwHandler: Kind::Simple,
#[doc="PG_LSN - PostgreSQL LSN datatype"]
3320 => PgLsn: Kind::Simple,
#[doc="PG_LSN[]"]
3321 => PgLsnArray: Kind::Array(Type::PgLsn),
#[doc="ANYENUM"]
3500 => Anyenum: Kind::Simple,
#[doc="TSVECTOR - text representation for text search"]
3614 => Tsvector: Kind::Simple,
#[doc="TSQUERY - query representation for text search"]
3615 => Tsquery: Kind::Simple,
#[doc="GTSVECTOR - GiST index internal text representation for text search"]
3642 => Gtsvector: Kind::Simple,
#[doc="TSVECTOR[]"]
3643 => TsvectorArray: Kind::Array(Type::Tsvector),
#[doc="GTSVECTOR[]"]
3644 => GtsvectorArray: Kind::Array(Type::Gtsvector),
#[doc="TSQUERY[]"]
3645 => TsqueryArray: Kind::Array(Type::Tsquery),
#[doc="REGCONFIG - registered text search configuration"]
3734 => Regconfig: Kind::Simple,
#[doc="REGCONFIG[]"]
3735 => RegconfigArray: Kind::Array(Type::Regconfig),
#[doc="REGDICTIONARY - registered text search dictionary"]
3769 => Regdictionary: Kind::Simple,
#[doc="REGDICTIONARY[]"]
3770 => RegdictionaryArray: Kind::Array(Type::Regdictionary),
2014-12-23 02:04:13 +00:00
#[doc="JSONB"]
2015-02-19 05:04:44 +00:00
3802 => Jsonb: Kind::Simple,
#[doc="ANYRANGE"]
3831 => Anyrange: Kind::Simple,
2014-12-23 02:04:13 +00:00
#[doc="JSONB[]"]
2015-02-19 05:04:44 +00:00
3807 => JsonbArray: Kind::Array(Type::Jsonb),
#[doc="INT4RANGE - range of integers"]
3904 => Int4Range: Kind::Range(Type::Int4),
2013-12-08 22:37:31 +00:00
#[doc="INT4RANGE[]"]
2015-02-19 05:04:44 +00:00
3905 => Int4RangeArray: Kind::Array(Type::Int4Range),
#[doc="NUMRANGE - range of numerics"]
3906 => NumRange: Kind::Range(Type::Numeric),
#[doc="NUMRANGE[]"]
3907 => NumRangeArray: Kind::Array(Type::NumRange),
#[doc="TSRANGE - range of timestamps without time zone"]
3908 => TsRange: Kind::Range(Type::Timestamp),
2013-12-08 23:02:38 +00:00
#[doc="TSRANGE[]"]
2015-02-19 05:04:44 +00:00
3909 => TsRangeArray: Kind::Array(Type::TsRange),
#[doc="TSTZRANGE - range of timestamps with time zone"]
3910 => TstzRange: Kind::Range(Type::TimestampTZ),
2013-12-08 23:02:38 +00:00
#[doc="TSTZRANGE[]"]
2015-02-19 05:04:44 +00:00
3911 => TstzRangeArray: Kind::Array(Type::TstzRange),
#[doc="DATERANGE - range of dates"]
3912 => DateRange: Kind::Range(Type::Date),
#[doc="DATERANGE[]"]
3913 => DateRangeArray: Kind::Array(Type::DateRange),
#[doc="INT8RANGE - range of bigints"]
3926 => Int8Range: Kind::Range(Type::Int8),
2013-12-08 23:07:11 +00:00
#[doc="INT8RANGE[]"]
2015-02-19 05:04:44 +00:00
3927 => Int8RangeArray: Kind::Array(Type::Int8Range),
#[doc="EVENT_TRIGGER"]
3838 => EventTrigger: Kind::Simple
2014-12-19 18:43:42 +00:00
}
/// A trait for types that can be created from a Postgres value.
pub trait FromSql: Sized {
/// Creates a new value of this type from a `Reader` of Postgres data.
2013-09-30 02:47:30 +00:00
///
/// If the value was `NULL`, the `Reader` will be `None`.
///
/// The caller of this method is responsible for ensuring that this type
/// is compatible with the Postgres `Type`.
///
/// The default implementation calls `FromSql::from_sql` when `raw` is
/// `Some` and returns `Err(Error::WasNull)` when `raw` is `None`. It does
/// not typically need to be overridden.
fn from_sql_nullable<R: Reader>(ty: &Type, raw: Option<&mut R>) -> Result<Self> {
match raw {
Some(raw) => FromSql::from_sql(ty, raw),
None => Err(Error::WasNull),
}
}
/// Creates a new value of this type from a `Reader` of Postgres data.
///
/// The caller of this method is responsible for ensuring that this type
/// is compatible with the Postgres `Type`.
fn from_sql<R: Reader>(ty: &Type, raw: &mut R) -> Result<Self>;
/// Determines if a value of this type can be created from the specified
/// Postgres `Type`.
fn accepts(ty: &Type) -> bool;
2013-10-31 02:55:25 +00:00
}
impl<T: FromSql> FromSql for Option<T> {
fn from_sql_nullable<R: Reader>(ty: &Type, raw: Option<&mut R>) -> Result<Option<T>> {
match raw {
Some(raw) => <T as FromSql>::from_sql(ty, raw).map(|e| Some(e)),
None => Ok(None),
}
}
fn from_sql<R: Reader>(ty: &Type, raw: &mut R) -> Result<Option<T>> {
<T as FromSql>::from_sql(ty, raw).map(|e| Some(e))
}
fn accepts(ty: &Type) -> bool {
<T as FromSql>::accepts(ty)
2013-12-07 23:39:44 +00:00
}
}
impl FromSql for bool {
fn from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<bool> {
Ok(try!(raw.read_u8()) != 0)
}
accepts!(Type::Bool);
}
impl FromSql for Vec<u8> {
fn from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<Vec<u8>> {
2014-11-17 17:43:10 +00:00
Ok(try!(raw.read_to_end()))
}
accepts!(Type::ByteA);
2014-11-17 17:43:10 +00:00
}
2013-12-08 22:37:31 +00:00
impl FromSql for String {
fn from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<String> {
2015-02-08 23:07:49 +00:00
String::from_utf8(try!(raw.read_to_end())).map_err(|_| Error::BadResponse)
2014-11-17 17:43:10 +00:00
}
fn accepts(ty: &Type) -> bool {
match *ty {
2015-02-19 05:04:44 +00:00
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => true,
Type::Other(ref u) if u.name() == "citext" => true,
_ => false,
}
}
2014-11-17 17:43:10 +00:00
}
macro_rules! primitive_from {
($t:ty, $f:ident, $($expected:pat),+) => {
impl FromSql for $t {
fn from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<$t> {
Ok(try!(raw.$f()))
}
2014-11-17 17:43:10 +00:00
accepts!($($expected),+);
}
}
}
primitive_from!(i8, read_i8, Type::Char);
primitive_from!(i16, read_be_i16, Type::Int2);
primitive_from!(i32, read_be_i32, Type::Int4);
primitive_from!(u32, read_be_u32, Type::Oid);
primitive_from!(i64, read_be_i64, Type::Int8);
primitive_from!(f32, read_be_f32, Type::Float4);
primitive_from!(f64, read_be_f64, Type::Float8);
impl FromSql for IpAddr {
fn from_sql<R: Reader>(_: &Type, raw: &mut R) -> Result<IpAddr> {
let family = try!(raw.read_u8());
let _bits = try!(raw.read_u8());
let _is_cidr = try!(raw.read_u8());
let nb = try!(raw.read_u8());
if nb > 16 {
2015-02-08 23:07:49 +00:00
return Err(Error::BadResponse);
}
2015-01-03 21:23:11 +00:00
let mut buf = [0u8; 16];
try!(raw.read_at_least(nb as usize, &mut buf));
let mut buf: &[u8] = &buf;
match family {
2 if nb == 4 => Ok(IpAddr::Ipv4Addr(buf[0], buf[1], buf[2], buf[3])),
3 if nb == 16 => Ok(IpAddr::Ipv6Addr(try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()),
try!(buf.read_be_u16()))),
2015-02-08 23:07:49 +00:00
_ => Err(Error::BadResponse),
}
}
accepts!(Type::Inet, Type::Cidr);
}
impl FromSql for HashMap<String, Option<String>> {
fn from_sql<R: Reader>(_: &Type, raw: &mut R)
-> Result<HashMap<String, Option<String>>> {
let mut map = HashMap::new();
let count = try!(raw.read_be_i32());
for _ in range(0, count) {
let key_len = try!(raw.read_be_i32());
let key = try!(raw.read_exact(key_len as usize));
let key = match String::from_utf8(key) {
Ok(key) => key,
Err(_) => return Err(Error::BadResponse),
};
let val_len = try!(raw.read_be_i32());
let val = if val_len < 0 {
None
} else {
let val = try!(raw.read_exact(val_len as usize));
match String::from_utf8(val) {
Ok(val) => Some(val),
Err(_) => return Err(Error::BadResponse),
}
};
map.insert(key, val);
}
Ok(map)
}
2013-12-06 05:58:22 +00:00
fn accepts(ty: &Type) -> bool {
2014-03-13 06:50:10 +00:00
match *ty {
2015-02-19 05:04:44 +00:00
Type::Other(ref u) if u.name() == "hstore" => true,
_ => false
2014-03-28 05:43:10 +00:00
}
2013-12-05 05:20:48 +00:00
}
2014-03-13 06:50:10 +00:00
}
2013-12-05 05:20:48 +00:00
2013-09-30 02:47:30 +00:00
/// A trait for types that can be converted into Postgres values
pub trait ToSql {
/// Converts the value of `self` into the binary format appropriate for the
/// Postgres backend.
2014-11-04 05:29:16 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>>;
}
/// A utility trait used by `ToSql` implementations.
pub trait RawToSql {
/// Converts the value of `self` into the binary format of the specified
/// Postgres type, writing it to `w`.
///
/// It is the caller's responsibility to make sure that this type can be
/// converted to the specified Postgres type.
fn raw_to_sql<W: Writer>(&self, ty: &Type, w: &mut W) -> Result<()>;
2013-10-31 02:55:25 +00:00
}
2013-12-07 23:39:44 +00:00
impl RawToSql for bool {
fn raw_to_sql<W: Writer>(&self, _: &Type, w: &mut W) -> Result<()> {
2014-11-17 06:54:57 +00:00
Ok(try!(w.write_u8(*self as u8)))
2013-12-07 23:39:44 +00:00
}
}
2014-03-15 06:01:46 +00:00
impl RawToSql for Vec<u8> {
fn raw_to_sql<W: Writer>(&self, _: &Type, w: &mut W) -> Result<()> {
2015-01-28 16:52:33 +00:00
Ok(try!(w.write_all(&**self)))
2014-03-15 06:01:46 +00:00
}
}
2014-05-26 03:38:40 +00:00
impl RawToSql for String {
fn raw_to_sql<W: Writer>(&self, _: &Type, w: &mut W) -> Result<()> {
2015-01-28 16:52:33 +00:00
Ok(try!(w.write_all(self.as_bytes())))
2013-12-08 03:13:21 +00:00
}
}
2014-12-19 18:43:42 +00:00
raw_to_impl!(i8, write_i8);
raw_to_impl!(i16, write_be_i16);
raw_to_impl!(i32, write_be_i32);
raw_to_impl!(u32, write_be_u32);
raw_to_impl!(i64, write_be_i64);
raw_to_impl!(f32, write_be_f32);
raw_to_impl!(f64, write_be_f64);
2013-10-31 02:55:25 +00:00
impl RawToSql for IpAddr {
fn raw_to_sql<W: Writer>(&self, _: &Type, raw: &mut W) -> Result<()> {
match *self {
IpAddr::Ipv4Addr(a, b, c, d) => {
2015-01-28 16:52:33 +00:00
try!(raw.write_all(&[2, // family
2015-02-15 19:18:39 +00:00
32, // bits
0, // is_cidr
4, // nb
a, b, c, d // addr
]));
}
IpAddr::Ipv6Addr(a, b, c, d, e, f, g, h) => {
2015-01-28 16:52:33 +00:00
try!(raw.write_all(&[3, // family
2015-02-15 19:18:39 +00:00
128, // bits
0, // is_cidr
16, // nb
]));
try!(raw.write_be_u16(a));
try!(raw.write_be_u16(b));
try!(raw.write_be_u16(c));
try!(raw.write_be_u16(d));
try!(raw.write_be_u16(e));
try!(raw.write_be_u16(f));
try!(raw.write_be_u16(g));
try!(raw.write_be_u16(h));
}
}
Ok(())
}
}
2015-01-09 18:26:24 +00:00
to_raw_to_impl!(Type::Bool; bool);
to_raw_to_impl!(Type::ByteA; Vec<u8>);
to_raw_to_impl!(Type::Inet, Type::Cidr; IpAddr);
to_raw_to_impl!(Type::Char; i8);
to_raw_to_impl!(Type::Int2; i16);
to_raw_to_impl!(Type::Int4; i32);
to_raw_to_impl!(Type::Oid; u32);
to_raw_to_impl!(Type::Int8; i64);
to_raw_to_impl!(Type::Float4; f32);
to_raw_to_impl!(Type::Float8; f64);
impl ToSql for String {
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
(&**self).to_sql(ty)
}
}
impl ToSql for Option<String> {
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
self.as_ref().map(|s| &**s).to_sql(ty)
}
}
impl<'a> ToSql for &'a str {
2014-11-04 05:29:16 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
match *ty {
2015-02-19 05:04:44 +00:00
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => {}
Type::Other(ref u) if u.name() == "citext" => {}
_ => return Err(Error::WrongType(ty.clone()))
}
Ok(Some(self.as_bytes().to_vec()))
}
}
impl<'a> ToSql for Option<&'a str> {
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
match *ty {
2015-02-19 05:04:44 +00:00
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => {}
Type::Other(ref u) if u.name() == "citext" => {}
_ => return Err(Error::WrongType(ty.clone()))
}
match *self {
Some(ref val) => val.to_sql(ty),
None => Ok(None)
}
}
}
impl<'a> ToSql for &'a [u8] {
2014-11-04 05:29:16 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2015-01-09 18:26:24 +00:00
check_types!(Type::ByteA; ty);
Ok(Some(self.to_vec()))
}
}
2015-01-09 18:26:24 +00:00
to_option_impl_lifetime!(Type::ByteA; &'a [u8]);
2014-12-19 18:43:42 +00:00
2014-05-26 03:38:40 +00:00
impl ToSql for HashMap<String, Option<String>> {
2014-11-04 05:29:16 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2014-03-13 06:50:10 +00:00
match *ty {
2015-02-19 05:04:44 +00:00
Type::Other(ref u) if u.name() == "hstore" => {}
_ => return Err(Error::WrongType(ty.clone()))
2014-03-13 06:50:10 +00:00
}
2014-11-20 04:54:32 +00:00
let mut buf = vec![];
2013-12-05 05:20:48 +00:00
2014-11-17 06:54:57 +00:00
try!(buf.write_be_i32(self.len() as i32));
2013-12-05 05:20:48 +00:00
for (key, val) in self.iter() {
2014-11-17 06:54:57 +00:00
try!(buf.write_be_i32(key.len() as i32));
2015-01-28 16:52:33 +00:00
try!(buf.write_all(key.as_bytes()));
2013-12-05 05:20:48 +00:00
match *val {
Some(ref val) => {
2014-11-17 06:54:57 +00:00
try!(buf.write_be_i32(val.len() as i32));
2015-01-28 16:52:33 +00:00
try!(buf.write_all(val.as_bytes()));
2013-12-05 05:20:48 +00:00
}
2014-11-17 06:54:57 +00:00
None => try!(buf.write_be_i32(-1))
2013-12-05 05:20:48 +00:00
}
}
2014-11-20 04:54:32 +00:00
Ok(Some(buf))
2013-12-05 05:20:48 +00:00
}
}
2014-03-13 06:50:10 +00:00
2014-05-26 03:38:40 +00:00
impl ToSql for Option<HashMap<String, Option<String>>> {
2014-11-04 05:29:16 +00:00
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
2014-03-13 06:50:10 +00:00
match *ty {
2015-02-19 05:04:44 +00:00
Type::Other(ref u) if u.name() == "hstore" => {}
_ => return Err(Error::WrongType(ty.clone()))
2014-03-13 06:50:10 +00:00
}
match *self {
Some(ref inner) => inner.to_sql(ty),
None => Ok(None)
2014-03-13 06:50:10 +00:00
}
}
}