2013-10-20 21:34:50 +00:00
|
|
|
//! Traits dealing with Postgres data types
|
2015-02-13 06:52:55 +00:00
|
|
|
|
2014-06-06 03:50:23 +00:00
|
|
|
use std::collections::HashMap;
|
2015-05-23 04:20:56 +00:00
|
|
|
use std::error;
|
2015-01-09 18:50:54 +00:00
|
|
|
use std::fmt;
|
2015-02-26 17:02:32 +00:00
|
|
|
use std::io::prelude::*;
|
|
|
|
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
|
2013-08-28 04:36:27 +00:00
|
|
|
|
2015-05-27 04:42:34 +00:00
|
|
|
pub use self::slice::Slice;
|
2015-09-27 05:57:36 +00:00
|
|
|
use {Result, SessionInfoNew, InnerConnection, OtherNew};
|
2014-11-21 05:47:13 +00:00
|
|
|
use error::Error;
|
2015-04-08 06:57:22 +00:00
|
|
|
use util;
|
2013-10-29 06:55:11 +00:00
|
|
|
|
2015-03-04 04:44:47 +00:00
|
|
|
/// Generates a simple implementation of `ToSql::accepts` which accepts the
|
|
|
|
/// types passed to it.
|
2015-02-15 23:11:15 +00:00
|
|
|
#[macro_export]
|
2015-02-15 01:07:10 +00:00
|
|
|
macro_rules! accepts {
|
|
|
|
($($expected:pat),+) => (
|
2015-02-28 04:46:43 +00:00
|
|
|
fn accepts(ty: &$crate::types::Type) -> bool {
|
2015-02-15 01:07:10 +00:00
|
|
|
match *ty {
|
|
|
|
$($expected)|+ => true,
|
|
|
|
_ => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2015-03-04 04:44:47 +00:00
|
|
|
/// Generates an implementation of `ToSql::to_sql_checked`.
|
|
|
|
///
|
|
|
|
/// All `ToSql` implementations should use this macro.
|
2015-02-15 23:11:15 +00:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! to_sql_checked {
|
|
|
|
() => {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql_checked(&self, ty: &$crate::types::Type, out: &mut ::std::io::Write,
|
|
|
|
ctx: &$crate::types::SessionInfo)
|
2015-02-28 04:46:43 +00:00
|
|
|
-> $crate::Result<$crate::types::IsNull> {
|
|
|
|
if !<Self as $crate::types::ToSql>::accepts(ty) {
|
2015-05-26 05:47:25 +00:00
|
|
|
return Err($crate::error::Error::WrongType(ty.clone()));
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
2015-11-13 05:18:10 +00:00
|
|
|
$crate::types::ToSql::to_sql(self, ty, out, ctx)
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
2014-12-19 18:43:42 +00:00
|
|
|
}
|
2014-12-15 00:43:17 +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;
|
2015-02-13 06:52:55 +00:00
|
|
|
mod slice;
|
2015-02-08 03:20:18 +00:00
|
|
|
#[cfg(feature = "rustc-serialize")]
|
2015-04-13 04:48:38 +00:00
|
|
|
mod rustc_serialize;
|
2015-11-08 00:28:20 +00:00
|
|
|
#[cfg(feature = "serde_json")]
|
|
|
|
mod serde_json;
|
2015-11-08 00:36:18 +00:00
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
mod serde;
|
2015-05-14 05:21:40 +00:00
|
|
|
#[cfg(feature = "chrono")]
|
|
|
|
mod chrono;
|
2013-10-29 05:35:52 +00:00
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
/// A structure providing information for conversion methods.
|
|
|
|
pub struct SessionInfo<'a> {
|
|
|
|
conn: &'a InnerConnection,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> SessionInfoNew<'a> for SessionInfo<'a> {
|
|
|
|
fn new(conn: &'a InnerConnection) -> SessionInfo<'a> {
|
|
|
|
SessionInfo {
|
|
|
|
conn: conn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> SessionInfo<'a> {
|
|
|
|
/// Returns the value of the specified Postgres backend parameter, such
|
|
|
|
/// as `timezone` or `server_version`.
|
|
|
|
pub fn parameter(&self, param: &str) -> Option<&'a str> {
|
|
|
|
self.conn.parameters.get(param).map(|s| &**s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-02 22:55:53 +00:00
|
|
|
/// A Postgres OID.
|
2014-01-03 07:10:26 +00:00
|
|
|
pub type Oid = u32;
|
2013-08-30 05:58:26 +00:00
|
|
|
|
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-09-27 05:57:36 +00:00
|
|
|
($(#[$doc:meta] $oid:tt: $name:expr => $variant:ident: $kind:expr),+) => (
|
2015-05-02 22:55:53 +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,
|
|
|
|
)+
|
2015-05-02 22:55:53 +00:00
|
|
|
/// An unknown type.
|
2015-02-19 05:04:44 +00:00
|
|
|
Other(Box<Other>),
|
2013-09-05 04:26:43 +00:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-27 05:57:36 +00:00
|
|
|
impl Type {
|
|
|
|
/// Returns the `Type` corresponding to the provided `Oid` if it
|
|
|
|
/// corresponds to a built-in type.
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2015-05-27 04:47:42 +00:00
|
|
|
|
2015-04-08 06:57:22 +00:00
|
|
|
/// Returns the OID of the `Type`.
|
|
|
|
pub fn oid(&self) -> Oid {
|
2013-12-08 19:44:37 +00:00
|
|
|
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-09-26 21:24:44 +00:00
|
|
|
/// Returns 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
|
|
|
}
|
|
|
|
}
|
2015-09-26 21:21:20 +00:00
|
|
|
|
2015-09-26 21:24:44 +00:00
|
|
|
/// Returns the schema of this type.
|
2015-09-26 21:21:20 +00:00
|
|
|
pub fn schema(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
Type::Other(ref u) => u.schema(),
|
|
|
|
_ => "pg_catalog",
|
|
|
|
}
|
|
|
|
}
|
2015-09-27 05:57:36 +00:00
|
|
|
|
|
|
|
/// Returns the name of this type.
|
|
|
|
pub fn name(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
$(
|
|
|
|
Type::$variant => $name,
|
|
|
|
)+
|
|
|
|
Type::Other(ref u) => u.name(),
|
|
|
|
}
|
|
|
|
}
|
2013-09-05 04:26:43 +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-11-14 19:38:16 +00:00
|
|
|
/// BOOL - boolean, 'true'/'false'
|
2015-09-27 05:57:36 +00:00
|
|
|
16: "bool" => Bool: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BYTEA - variable-length string, binary values escaped
|
2015-09-27 05:57:36 +00:00
|
|
|
17: "bytea" => Bytea: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// "char" - single character
|
2015-09-27 05:57:36 +00:00
|
|
|
18: "char" => Char: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NAME - 63-byte type for storing system identifiers
|
2015-09-27 05:57:36 +00:00
|
|
|
19: "name" => Name: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT8/BIGINT - ~18 digit integer, 8-byte storage
|
2015-09-27 05:57:36 +00:00
|
|
|
20: "int8" => Int8: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT2/SMALLINT - -32 thousand to 32 thousand, 2-byte storage
|
2015-09-27 05:57:36 +00:00
|
|
|
21: "int2" => Int2: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT2VECTOR - array of int2, used in system tables
|
2015-09-27 05:57:36 +00:00
|
|
|
22: "int2vector" => Int2Vector: Kind::Array(Type::Int2),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT4/INT - -2 billion to 2 billion integer, 4-byte storage
|
2015-09-27 05:57:36 +00:00
|
|
|
23: "int4" => Int4: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGPROC - registered procedure
|
2015-09-27 05:57:36 +00:00
|
|
|
24: "regproc" => Regproc: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TEXT - variable-length string, no limit specified
|
2015-09-27 05:57:36 +00:00
|
|
|
25: "text" => Text: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// OID - object identifier(oid), maximum 4 billion
|
2015-09-27 05:57:36 +00:00
|
|
|
26: "oid" => Oid: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TID - (block, offset), physical location of tuple
|
2015-09-27 05:57:36 +00:00
|
|
|
27: "tid" => Tid: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// XID - transaction id
|
2015-09-27 05:57:36 +00:00
|
|
|
28: "xid" => Xid: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CID - command identifier type, sequence in transaction id
|
2015-09-27 05:57:36 +00:00
|
|
|
29: "cid" => Cid: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// OIDVECTOR - array of oids, used in system tables
|
2015-09-27 05:57:36 +00:00
|
|
|
30: "oidvector" => OidVector: Kind::Array(Type::Oid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_TYPE
|
2015-09-27 05:57:36 +00:00
|
|
|
71: "pg_type" => PgType: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_ATTRIBUTE
|
2015-09-27 05:57:36 +00:00
|
|
|
75: "pg_attribute" => PgAttribute: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_PROC
|
2015-09-27 05:57:36 +00:00
|
|
|
81: "pg_proc" => PgProc: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_CLASS
|
2015-09-27 05:57:36 +00:00
|
|
|
83: "pg_class" => PgClass: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// JSON
|
2015-09-27 05:57:36 +00:00
|
|
|
114: "json" => Json: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// XML - XML content
|
2015-09-27 05:57:36 +00:00
|
|
|
142: "xml" => Xml: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// XML[]
|
2015-09-27 05:57:36 +00:00
|
|
|
143: "_xml" => XmlArray: Kind::Array(Type::Xml),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_NODE_TREE - string representing an internal node tree
|
2015-09-27 05:57:36 +00:00
|
|
|
194: "pg_node_tree" => PgNodeTree: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// JSON[]
|
2015-09-27 05:57:36 +00:00
|
|
|
199: "_json" => JsonArray: Kind::Array(Type::Json),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// SMGR - storage manager
|
2015-09-27 05:57:36 +00:00
|
|
|
210: "smgr" => Smgr: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// POINT - geometric point '(x, y)'
|
2015-09-27 05:57:36 +00:00
|
|
|
600: "point" => Point: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// LSEG - geometric line segment '(pt1,pt2)'
|
2015-09-27 05:57:36 +00:00
|
|
|
601: "lseg" => Lseg: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PATH - geometric path '(pt1,...)'
|
2015-09-27 05:57:36 +00:00
|
|
|
602: "path" => Path: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BOX - geometric box '(lower left,upper right)'
|
2015-09-27 05:57:36 +00:00
|
|
|
603: "box" => Box: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// POLYGON - geometric polygon '(pt1,...)'
|
2015-09-27 05:57:36 +00:00
|
|
|
604: "polygon" => Polygon: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// LINE - geometric line
|
2015-09-27 05:57:36 +00:00
|
|
|
628: "line" => Line: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// LINE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
629: "_line" => LineArray: Kind::Array(Type::Line),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CIDR - network IP address/netmask, network address
|
2015-09-27 05:57:36 +00:00
|
|
|
650: "cidr" => Cidr: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CIDR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
651: "_cidr" => CidrArray: Kind::Array(Type::Cidr),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// FLOAT4/REAL - single-precision floating point number, 4-byte storage
|
2015-09-27 05:57:36 +00:00
|
|
|
700: "float4" => Float4: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// FLOAT8/DOUBLE PRECISION - double-precision floating point number, 8-byte storage
|
2015-09-27 05:57:36 +00:00
|
|
|
701: "float8" => Float8: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ABSTIME - absolute, limited-range date and time (Unix system time)
|
2015-09-27 05:57:36 +00:00
|
|
|
702: "abstime" => Abstime: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// RELTIME - relative, limited-range date and time (Unix delta time)
|
2015-09-27 05:57:36 +00:00
|
|
|
703: "reltime" => Reltime: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TINTERVAL - (abstime,abstime), time interval
|
2015-09-27 05:57:36 +00:00
|
|
|
704: "tinterval" => Tinterval: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// UNKNOWN
|
2015-09-27 05:57:36 +00:00
|
|
|
705: "unknown" => Unknown: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CIRCLE - geometric circle '(center,radius)'
|
2015-09-27 05:57:36 +00:00
|
|
|
718: "circle" => Circle: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CIRCLE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
719: "_circle" => CircleArray: Kind::Array(Type::Circle),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// MONEY - monetary amounts, $d,ddd.cc
|
2015-09-27 05:57:36 +00:00
|
|
|
790: "money" => Money: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// MONEY[]
|
2015-09-27 05:57:36 +00:00
|
|
|
791: "_money" => MoneyArray: Kind::Array(Type::Money),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// MACADDR - XX:XX:XX:XX:XX:XX, MAC address
|
2015-09-27 05:57:36 +00:00
|
|
|
829: "macaddr" => Macaddr: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INET - IP address/netmask, host address, netmask optional
|
2015-09-27 05:57:36 +00:00
|
|
|
869: "inet" => Inet: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BOOL[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1000: "_bool" => BoolArray: Kind::Array(Type::Bool),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BYTEA[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1001: "_bytea" => ByteaArray: Kind::Array(Type::Bytea),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// "char"[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1002: "_char" => CharArray: Kind::Array(Type::Char),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NAME[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1003: "_name" => NameArray: Kind::Array(Type::Name),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT2[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1005: "_int2" => Int2Array: Kind::Array(Type::Int2),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT2VECTOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1006: "_int2vector" => Int2VectorArray: Kind::Array(Type::Int2Vector),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT4[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1007: "_int4" => Int4Array: Kind::Array(Type::Int4),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGPROC[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1008: "_regproc" => RegprocArray: Kind::Array(Type::Regproc),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TEXT[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1009: "_text" => TextArray: Kind::Array(Type::Text),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TID[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1010: "_tid" => TidArray: Kind::Array(Type::Tid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// XID[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1011: "_xid" => XidArray: Kind::Array(Type::Xid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CID[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1012: "_cid" => CidArray: Kind::Array(Type::Cid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// OIDVECTOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1013: "_oidvector" => OidVectorArray: Kind::Array(Type::OidVector),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BPCHAR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1014: "_bpchar" => BpcharArray: Kind::Array(Type::Bpchar),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// VARCHAR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1015: "_varchar" => VarcharArray: Kind::Array(Type::Varchar),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT8[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1016: "_int8" => Int8Array: Kind::Array(Type::Int8),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// POINT[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1017: "_point" => PointArray: Kind::Array(Type::Point),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// LSEG[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1018: "_lseg" => LsegArray: Kind::Array(Type::Lseg),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PATH[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1019: "_path" => PathArray: Kind::Array(Type::Path),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BOX[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1020: "_box" => BoxArray: Kind::Array(Type::Box),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// FLOAT4[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1021: "_float4" => Float4Array: Kind::Array(Type::Float4),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// FLOAT8[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1022: "_float8" => Float8Array: Kind::Array(Type::Float8),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ABSTIME[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1023: "_abstime" => AbstimeArray: Kind::Array(Type::Abstime),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// RELTIME[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1024: "_reltime" => ReltimeArray: Kind::Array(Type::Reltime),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TINTERVAL[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1025: "_tinterval" => TintervalArray: Kind::Array(Type::Tinterval),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// POLYGON[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1027: "_polygon" => PolygonArray: Kind::Array(Type::Polygon),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// OID[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1028: "_oid" => OidArray: Kind::Array(Type::Oid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ACLITEM - access control list
|
2015-09-27 05:57:36 +00:00
|
|
|
1033: "aclitem" => Aclitem: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ACLITEM[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1034: "_aclitem" => AclitemArray: Kind::Array(Type::Aclitem),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// MACADDR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1040: "_macaddr" => MacaddrArray: Kind::Array(Type::Macaddr),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INET[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1041: "_inet" => InetArray: Kind::Array(Type::Inet),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BPCHAR - char(length), blank-padded string, fixed storage length
|
2015-09-27 05:57:36 +00:00
|
|
|
1042: "bpchar" => Bpchar: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// VARCHAR - varchar(length), non-blank-padded string, variable storage length
|
2015-09-27 05:57:36 +00:00
|
|
|
1043: "varchar" => Varchar: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// DATE - date
|
2015-09-27 05:57:36 +00:00
|
|
|
1082: "date" => Date: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIME - time of day
|
2015-09-27 05:57:36 +00:00
|
|
|
1083: "time" => Time: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMESTAMP - date and time
|
2015-09-27 05:57:36 +00:00
|
|
|
1114: "timestamp" => Timestamp: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMESTAMP[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1115: "_timestamp" => TimestampArray: Kind::Array(Type::Timestamp),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// DATE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1182: "_date" => DateArray: Kind::Array(Type::Date),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIME[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1183: "_time" => TimeArray: Kind::Array(Type::Time),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMESTAMPTZ - date and time with time zone
|
2015-09-27 05:57:36 +00:00
|
|
|
1184: "timestamptz" => TimestampTZ: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMESTAMPTZ[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1185: "_timestamptz" => TimestampTZArray: Kind::Array(Type::TimestampTZ),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INTERVAL - @ <number> <units>, time interval
|
2015-09-27 05:57:36 +00:00
|
|
|
1186: "interval" => Interval: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INTERVAL[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1187: "_interval" => IntervalArray: Kind::Array(Type::Interval),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NUMERIC[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1231: "_numeric" => NumericArray: Kind::Array(Type::Numeric),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CSTRING[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1263: "_cstring" => CstringArray: Kind::Array(Type::Cstring),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMETZ - time of day with time zone
|
2015-09-27 05:57:36 +00:00
|
|
|
1266: "timetz" => Timetz: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TIMETZ[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1270: "_timetz" => TimetzArray: Kind::Array(Type::Timetz),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BIT - fixed-length bit string
|
2015-09-27 05:57:36 +00:00
|
|
|
1560: "bit" => Bit: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// BIT[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1561: "_bit" => BitArray: Kind::Array(Type::Bit),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// VARBIT - variable-length bit string
|
2015-09-27 05:57:36 +00:00
|
|
|
1562: "varbit" => Varbit: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// VARBIT[]
|
2015-09-27 05:57:36 +00:00
|
|
|
1563: "_varbit" => VarbitArray: Kind::Array(Type::Varbit),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NUMERIC - numeric(precision, decimal), arbitrary precision number
|
2015-09-27 05:57:36 +00:00
|
|
|
1700: "numeric" => Numeric: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REFCURSOR - reference to cursor (portal name)
|
2015-09-27 05:57:36 +00:00
|
|
|
1790: "refcursor" => Refcursor: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REFCURSOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2201: "_refcursor" => RefcursorArray: Kind::Array(Type::Refcursor),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGPROCEDURE - registered procedure (with args)
|
2015-09-27 05:57:36 +00:00
|
|
|
2202: "regprocedure" => Regprocedure: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGOPER - registered operator
|
2015-09-27 05:57:36 +00:00
|
|
|
2203: "regoper" => Regoper: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGOPERATOR - registered operator (with args)
|
2015-09-27 05:57:36 +00:00
|
|
|
2204: "regoperator" => Regoperator: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGCLASS - registered class
|
2015-09-27 05:57:36 +00:00
|
|
|
2205: "regclass" => Regclass: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGTYPE - registered type
|
2015-09-27 05:57:36 +00:00
|
|
|
2206: "regtype" => Regtype: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGPROCEDURE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2207: "_regprocedure" => RegprocedureArray: Kind::Array(Type::Regprocedure),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGOPER[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2208: "_regoper" => RegoperArray: Kind::Array(Type::Regoper),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGOPERATOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2209: "_regoperator" => RegoperatorArray: Kind::Array(Type::Regoperator),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGCLASS[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2210: "_regclass" => RegclassArray: Kind::Array(Type::Regclass),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGTYPE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2211: "_regtype" => RegtypeArray: Kind::Array(Type::Regtype),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// RECORD
|
2015-09-27 05:57:36 +00:00
|
|
|
2249: "record" => Record: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// CSTRING
|
2015-09-27 05:57:36 +00:00
|
|
|
2275: "cstring" => Cstring: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANY
|
2015-09-27 05:57:36 +00:00
|
|
|
2276: "any" => Any: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANYARRAY
|
2015-09-27 05:57:36 +00:00
|
|
|
2277: "anyarray" => AnyArray: Kind::Array(Type::Any),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// VOID
|
2015-09-27 05:57:36 +00:00
|
|
|
2278: "void" => Void: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TRIGGER
|
2015-09-27 05:57:36 +00:00
|
|
|
2279: "trigger" => Trigger: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// LANGUAGE_HANDLER
|
2015-09-27 05:57:36 +00:00
|
|
|
2280: "language_handler" => LanguageHandler: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INTERNAL
|
2015-09-27 05:57:36 +00:00
|
|
|
2281: "internal" => Internal: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// OPAQUE
|
2015-09-27 05:57:36 +00:00
|
|
|
2282: "opaque" => Opaque: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANYELEMENT
|
2015-09-27 05:57:36 +00:00
|
|
|
2283: "anyelement" => Anyelement: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// RECORD[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2287: "_record" => RecordArray: Kind::Array(Type::Record),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANYNONARRAY
|
2015-09-27 05:57:36 +00:00
|
|
|
2776: "anynonarray" => Anynonarray: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TXID_SNAPSHOT[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2949: "_txid_snapshot" => TxidSnapshotArray: Kind::Array(Type::TxidSnapshot),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// UUID - UUID datatype
|
2015-09-27 05:57:36 +00:00
|
|
|
2950: "uuid" => Uuid: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TXID_SNAPSHOT - txid snapshot
|
2015-09-27 05:57:36 +00:00
|
|
|
2970: "txid_snapshot" => TxidSnapshot: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// UUID[]
|
2015-09-27 05:57:36 +00:00
|
|
|
2951: "_uuid" => UuidArray: Kind::Array(Type::Uuid),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// FDW_HANDLER
|
2015-09-27 05:57:36 +00:00
|
|
|
3115: "fdw_handler" => FdwHandler: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_LSN - PostgreSQL LSN datatype
|
2015-09-27 05:57:36 +00:00
|
|
|
3220: "pg_lsn" => PgLsn: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// PG_LSN[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3221: "_pg_lsn" => PgLsnArray: Kind::Array(Type::PgLsn),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANYENUM
|
2015-09-27 05:57:36 +00:00
|
|
|
3500: "anyenum" => Anyenum: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSVECTOR - text representation for text search
|
2015-09-27 05:57:36 +00:00
|
|
|
3614: "tsvector" => Tsvector: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSQUERY - query representation for text search
|
2015-09-27 05:57:36 +00:00
|
|
|
3615: "tsquery" => Tsquery: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// GTSVECTOR - GiST index internal text representation for text search
|
2015-09-27 05:57:36 +00:00
|
|
|
3642: "gtsvector" => Gtsvector: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSVECTOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3643: "_tsvector" => TsvectorArray: Kind::Array(Type::Tsvector),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// GTSVECTOR[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3644: "_gtsvector" => GtsvectorArray: Kind::Array(Type::Gtsvector),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSQUERY[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3645: "_tsquery" => TsqueryArray: Kind::Array(Type::Tsquery),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGCONFIG - registered text search configuration
|
2015-09-27 05:57:36 +00:00
|
|
|
3734: "regconfig" => Regconfig: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGCONFIG[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3735: "_regconfig" => RegconfigArray: Kind::Array(Type::Regconfig),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGDICTIONARY - registered text search dictionary
|
2015-09-27 05:57:36 +00:00
|
|
|
3769: "regdictionary" => Regdictionary: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// REGDICTIONARY[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3770: "_regdictionary" => RegdictionaryArray: Kind::Array(Type::Regdictionary),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// JSONB
|
2015-09-27 05:57:36 +00:00
|
|
|
3802: "jsonb" => Jsonb: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// ANYRANGE
|
2015-09-27 05:57:36 +00:00
|
|
|
3831: "anyrange" => Anyrange: Kind::Simple,
|
2015-11-14 19:38:16 +00:00
|
|
|
/// JSONB[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3807: "_jsonb" => JsonbArray: Kind::Array(Type::Jsonb),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT4RANGE - range of integers
|
2015-09-27 05:57:36 +00:00
|
|
|
3904: "int4range" => Int4Range: Kind::Range(Type::Int4),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT4RANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3905: "_int4range" => Int4RangeArray: Kind::Array(Type::Int4Range),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NUMRANGE - range of numerics
|
2015-09-27 05:57:36 +00:00
|
|
|
3906: "numrange" => NumRange: Kind::Range(Type::Numeric),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// NUMRANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3907: "_numrange" => NumRangeArray: Kind::Array(Type::NumRange),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSRANGE - range of timestamps without time zone
|
2015-09-27 05:57:36 +00:00
|
|
|
3908: "tsrange" => TsRange: Kind::Range(Type::Timestamp),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSRANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3909: "_tsrange" => TsRangeArray: Kind::Array(Type::TsRange),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSTZRANGE - range of timestamps with time zone
|
2015-09-27 05:57:36 +00:00
|
|
|
3910: "tstzrange" => TstzRange: Kind::Range(Type::TimestampTZ),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// TSTZRANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3911: "_tstzrange" => TstzRangeArray: Kind::Array(Type::TstzRange),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// DATERANGE - range of dates
|
2015-09-27 05:57:36 +00:00
|
|
|
3912: "daterange" => DateRange: Kind::Range(Type::Date),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// DATERANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3913: "_daterange" => DateRangeArray: Kind::Array(Type::DateRange),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT8RANGE - range of bigints
|
2015-09-27 05:57:36 +00:00
|
|
|
3926: "int8range" => Int8Range: Kind::Range(Type::Int8),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// INT8RANGE[]
|
2015-09-27 05:57:36 +00:00
|
|
|
3927: "_int8range" => Int8RangeArray: Kind::Array(Type::Int8Range),
|
2015-11-14 19:38:16 +00:00
|
|
|
/// EVENT_TRIGGER
|
2015-09-27 05:57:36 +00:00
|
|
|
3838: "event_trigger" => EventTrigger: Kind::Simple
|
2014-12-19 18:43:42 +00:00
|
|
|
}
|
2013-09-02 19:42:24 +00:00
|
|
|
|
2015-05-23 02:51:44 +00:00
|
|
|
/// Information about an unknown type.
|
|
|
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
|
|
|
pub struct Other {
|
|
|
|
name: String,
|
|
|
|
oid: Oid,
|
|
|
|
kind: Kind,
|
2015-09-26 20:23:55 +00:00
|
|
|
schema: String,
|
2015-05-23 02:51:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl OtherNew for Other {
|
2015-09-26 20:23:55 +00:00
|
|
|
fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other {
|
2015-05-23 02:51:44 +00:00
|
|
|
Other {
|
|
|
|
name: name,
|
|
|
|
oid: oid,
|
|
|
|
kind: kind,
|
2015-09-26 20:23:55 +00:00
|
|
|
schema: schema,
|
2015-05-23 02:51:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Other {
|
|
|
|
/// The name of the type.
|
|
|
|
pub fn name(&self) -> &str {
|
|
|
|
&self.name
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The OID of this type.
|
|
|
|
pub fn oid(&self) -> Oid {
|
|
|
|
self.oid
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The kind of this type.
|
|
|
|
pub fn kind(&self) -> &Kind {
|
|
|
|
&self.kind
|
|
|
|
}
|
2015-09-26 20:23:55 +00:00
|
|
|
|
|
|
|
/// The schema of this type.
|
|
|
|
pub fn schema(&self) -> &str {
|
|
|
|
&self.schema
|
|
|
|
}
|
2015-05-23 02:51:44 +00:00
|
|
|
}
|
|
|
|
|
2015-05-23 04:20:56 +00:00
|
|
|
/// An error indicating that a `NULL` Postgres value was passed to a `FromSql`
|
|
|
|
/// implementation that does not support `NULL` values.
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub struct WasNull;
|
|
|
|
|
|
|
|
impl fmt::Display for WasNull {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
fmt.write_str(error::Error::description(self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for WasNull {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
"a Postgres value was `NULL`"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
/// A trait for types that can be created from a Postgres value.
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
|
|
|
/// # Types
|
|
|
|
///
|
|
|
|
/// The following implementations are provided by this crate, along with the
|
|
|
|
/// corresponding Postgres types:
|
|
|
|
///
|
|
|
|
/// | Rust type | Postgres type(s) |
|
|
|
|
/// |---------------------------------------------|--------------------------------|
|
|
|
|
/// | bool | BOOL |
|
|
|
|
/// | i8 | "char" |
|
|
|
|
/// | i16 | SMALLINT, SMALLSERIAL |
|
|
|
|
/// | i32 | INT, SERIAL |
|
|
|
|
/// | u32 | OID |
|
|
|
|
/// | i64 | BIGINT, BIGSERIAL |
|
|
|
|
/// | f32 | REAL |
|
|
|
|
/// | f64 | DOUBLE PRECISION |
|
|
|
|
/// | String | VARCHAR, CHAR(n), TEXT, CITEXT |
|
|
|
|
/// | Vec<u8> | BYTEA |
|
|
|
|
/// | HashMap<String, Option<String>> | HSTORE |
|
|
|
|
///
|
|
|
|
/// In addition, some implementations are provided for types in third party
|
|
|
|
/// crates. These are disabled by default; to opt into one of these
|
2015-05-18 03:34:49 +00:00
|
|
|
/// implementations, activate the Cargo feature corresponding to the crate's
|
2015-11-08 00:28:20 +00:00
|
|
|
/// name. For example, the `serde_json` feature enables the implementation for
|
|
|
|
/// the `serde_json::Value` type.
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
2015-07-21 06:16:50 +00:00
|
|
|
/// | Rust type | Postgres type(s) |
|
|
|
|
/// |-------------------------------------|-------------------------------------|
|
|
|
|
/// | serialize::json::Json | JSON, JSONB |
|
2015-11-08 00:28:20 +00:00
|
|
|
/// | serde_json::Value | JSON, JSONB |
|
2015-07-21 06:16:50 +00:00
|
|
|
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::NaiveDateTime | TIMESTAMP |
|
|
|
|
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::DateTime<Local> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::DateTime<FixedOffset> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::NaiveDate | DATE |
|
|
|
|
/// | chrono::NaiveTime | TIME |
|
|
|
|
/// | uuid::Uuid | UUID |
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
|
|
|
/// # Nullability
|
|
|
|
///
|
|
|
|
/// In addition to the types listed above, `FromSql` is implemented for
|
|
|
|
/// `Option<T>` where `T` implements `FromSql`. An `Option<T>` represents a
|
|
|
|
/// nullable Postgres value.
|
2015-02-15 01:07:10 +00:00
|
|
|
pub trait FromSql: Sized {
|
2015-10-25 02:24:00 +00:00
|
|
|
/// ### Deprecated
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql_nullable<R: Read>(ty: &Type, raw: Option<&mut R>, ctx: &SessionInfo)
|
|
|
|
-> Result<Self> {
|
2015-02-15 01:07:10 +00:00
|
|
|
match raw {
|
2015-05-22 05:28:51 +00:00
|
|
|
Some(raw) => FromSql::from_sql(ty, raw, ctx),
|
2015-10-25 02:24:00 +00:00
|
|
|
None => FromSql::from_sql_null(ty, ctx),
|
2015-02-15 01:07:10 +00:00
|
|
|
}
|
|
|
|
}
|
2013-08-28 04:36:27 +00:00
|
|
|
|
2015-04-08 06:57:22 +00:00
|
|
|
/// Creates a new value of this type from a `Read`er of the binary format
|
2015-02-15 23:31:07 +00:00
|
|
|
/// of the specified Postgres `Type`.
|
2015-01-22 06:31:04 +00:00
|
|
|
///
|
2015-02-15 01:07:10 +00:00
|
|
|
/// The caller of this method is responsible for ensuring that this type
|
|
|
|
/// is compatible with the Postgres `Type`.
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Self>;
|
2015-02-15 01:07:10 +00:00
|
|
|
|
2015-10-25 02:24:00 +00:00
|
|
|
/// Creates a new value of this type from a `NULL` SQL value.
|
|
|
|
///
|
|
|
|
/// The caller of this method is responsible for ensuring that this type
|
|
|
|
/// is compatible with the Postgres `Type`.
|
|
|
|
///
|
|
|
|
/// The default implementation returns
|
|
|
|
/// `Err(Error::Conversion(Box::new(WasNull))`.
|
2015-11-08 00:28:20 +00:00
|
|
|
#[allow(unused_variables)]
|
2015-10-25 02:24:00 +00:00
|
|
|
fn from_sql_null(ty: &Type, ctx: &SessionInfo) -> Result<Self> {
|
|
|
|
Err(Error::Conversion(Box::new(WasNull)))
|
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
/// 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
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
impl<T: FromSql> FromSql for Option<T> {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Option<T>> {
|
|
|
|
<T as FromSql>::from_sql(ty, raw, ctx).map(Some)
|
2015-02-15 01:07:10 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 02:24:00 +00:00
|
|
|
fn from_sql_null(_: &Type, _: &SessionInfo) -> Result<Option<T>> {
|
|
|
|
Ok(None)
|
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
fn accepts(ty: &Type) -> bool {
|
|
|
|
<T as FromSql>::accepts(ty)
|
2013-12-07 23:39:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
impl FromSql for bool {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<bool> {
|
2015-02-15 01:07:10 +00:00
|
|
|
Ok(try!(raw.read_u8()) != 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
accepts!(Type::Bool);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromSql for Vec<u8> {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<Vec<u8>> {
|
2015-02-26 17:02:32 +00:00
|
|
|
let mut buf = vec![];
|
|
|
|
try!(raw.read_to_end(&mut buf));
|
|
|
|
Ok(buf)
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
2015-02-15 01:07:10 +00:00
|
|
|
|
2015-02-19 07:30:06 +00:00
|
|
|
accepts!(Type::Bytea);
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
2013-12-08 22:37:31 +00:00
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
impl FromSql for String {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<String> {
|
2015-02-26 17:02:32 +00:00
|
|
|
let mut buf = vec![];
|
|
|
|
try!(raw.read_to_end(&mut buf));
|
2015-05-23 04:20:56 +00:00
|
|
|
String::from_utf8(buf).map_err(|err| Error::Conversion(Box::new(err)))
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
2015-02-15 01:07: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,
|
2015-02-15 01:07:10 +00:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2014-11-17 17:43:10 +00:00
|
|
|
}
|
|
|
|
|
2015-05-02 22:55:53 +00:00
|
|
|
impl FromSql for i8 {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<i8> {
|
2015-05-02 22:55:53 +00:00
|
|
|
Ok(try!(raw.read_i8()))
|
|
|
|
}
|
|
|
|
|
|
|
|
accepts!(Type::Char);
|
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
macro_rules! primitive_from {
|
|
|
|
($t:ty, $f:ident, $($expected:pat),+) => {
|
|
|
|
impl FromSql for $t {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<$t> {
|
2015-02-26 17:02:32 +00:00
|
|
|
Ok(try!(raw.$f::<BigEndian>()))
|
2015-02-15 01:07:10 +00:00
|
|
|
}
|
2014-11-17 17:43:10 +00:00
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
accepts!($($expected),+);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-26 17:02:32 +00:00
|
|
|
primitive_from!(i16, read_i16, Type::Int2);
|
|
|
|
primitive_from!(i32, read_i32, Type::Int4);
|
|
|
|
primitive_from!(u32, read_u32, Type::Oid);
|
|
|
|
primitive_from!(i64, read_i64, Type::Int8);
|
|
|
|
primitive_from!(f32, read_f32, Type::Float4);
|
|
|
|
primitive_from!(f64, read_f64, Type::Float8);
|
2015-02-15 01:07:10 +00:00
|
|
|
|
|
|
|
impl FromSql for HashMap<String, Option<String>> {
|
2015-05-22 05:28:51 +00:00
|
|
|
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo)
|
|
|
|
-> Result<HashMap<String, Option<String>>> {
|
2015-02-15 01:07:10 +00:00
|
|
|
let mut map = HashMap::new();
|
|
|
|
|
2015-02-26 17:02:32 +00:00
|
|
|
let count = try!(raw.read_i32::<BigEndian>());
|
2015-02-15 01:07:10 +00:00
|
|
|
|
2015-02-26 17:02:32 +00:00
|
|
|
for _ in 0..count {
|
|
|
|
let key_len = try!(raw.read_i32::<BigEndian>());
|
2015-05-02 22:55:53 +00:00
|
|
|
let mut key = vec![0; key_len as usize];
|
2015-04-08 06:57:22 +00:00
|
|
|
try!(util::read_all(raw, &mut key));
|
2015-02-15 01:07:10 +00:00
|
|
|
let key = match String::from_utf8(key) {
|
|
|
|
Ok(key) => key,
|
2015-05-23 04:20:56 +00:00
|
|
|
Err(err) => return Err(Error::Conversion(Box::new(err))),
|
2015-02-15 01:07:10 +00:00
|
|
|
};
|
|
|
|
|
2015-02-26 17:02:32 +00:00
|
|
|
let val_len = try!(raw.read_i32::<BigEndian>());
|
2015-02-15 01:07:10 +00:00
|
|
|
let val = if val_len < 0 {
|
|
|
|
None
|
|
|
|
} else {
|
2015-05-02 22:55:53 +00:00
|
|
|
let mut val = vec![0; val_len as usize];
|
2015-04-08 06:57:22 +00:00
|
|
|
try!(util::read_all(raw, &mut val));
|
2015-02-15 01:07:10 +00:00
|
|
|
match String::from_utf8(val) {
|
|
|
|
Ok(val) => Some(val),
|
2015-05-23 04:20:56 +00:00
|
|
|
Err(err) => return Err(Error::Conversion(Box::new(err))),
|
2015-02-15 01:07:10 +00:00
|
|
|
}
|
|
|
|
};
|
2014-12-15 00:43:17 +00:00
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
map.insert(key, val);
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 01:07:10 +00:00
|
|
|
Ok(map)
|
|
|
|
}
|
2013-12-06 05:58:22 +00:00
|
|
|
|
2015-02-15 01:07:10 +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,
|
2015-02-15 01:07:10 +00:00
|
|
|
_ => 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
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
/// An enum representing the nullability of a Postgres value.
|
|
|
|
pub enum IsNull {
|
|
|
|
/// The value is NULL.
|
|
|
|
Yes,
|
|
|
|
/// The value is not NULL.
|
|
|
|
No,
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
/// A trait for types that can be converted into Postgres values.
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
|
|
|
/// # Types
|
|
|
|
///
|
|
|
|
/// The following implementations are provided by this crate, along with the
|
|
|
|
/// corresponding Postgres types:
|
|
|
|
///
|
|
|
|
/// | Rust type | Postgres type(s) |
|
|
|
|
/// |---------------------------------------------|--------------------------------|
|
|
|
|
/// | bool | BOOL |
|
|
|
|
/// | i8 | "char" |
|
|
|
|
/// | i16 | SMALLINT, SMALLSERIAL |
|
|
|
|
/// | i32 | INT, SERIAL |
|
|
|
|
/// | u32 | OID |
|
|
|
|
/// | i64 | BIGINT, BIGSERIAL |
|
|
|
|
/// | f32 | REAL |
|
|
|
|
/// | f64 | DOUBLE PRECISION |
|
|
|
|
/// | String | VARCHAR, CHAR(n), TEXT, CITEXT |
|
|
|
|
/// | &str | VARCHAR, CHAR(n), TEXT, CITEXT |
|
|
|
|
/// | Vec<u8> | BYTEA |
|
|
|
|
/// | &[u8] | BYTEA |
|
|
|
|
/// | HashMap<String, Option<String>> | HSTORE |
|
|
|
|
///
|
|
|
|
/// In addition, some implementations are provided for types in third party
|
|
|
|
/// crates. These are disabled by default; to opt into one of these
|
2015-05-18 03:34:49 +00:00
|
|
|
/// implementations, activate the Cargo feature corresponding to the crate's
|
2015-11-08 00:28:20 +00:00
|
|
|
/// name. For example, the `serde_json` feature enables the implementation for
|
|
|
|
/// the `serde_json::Value` type.
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
2015-07-21 06:16:50 +00:00
|
|
|
/// | Rust type | Postgres type(s) |
|
|
|
|
/// |-------------------------------------|-------------------------------------|
|
|
|
|
/// | serialize::json::Json | JSON, JSONB |
|
2015-11-08 00:28:20 +00:00
|
|
|
/// | serde_json::Value | JSON, JSONB |
|
2015-07-21 06:16:50 +00:00
|
|
|
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::NaiveDateTime | TIMESTAMP |
|
|
|
|
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::DateTime<Local> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::DateTime<FixedOffset> | TIMESTAMP WITH TIME ZONE |
|
|
|
|
/// | chrono::NaiveDate | DATE |
|
|
|
|
/// | chrono::NaiveTime | TIME |
|
|
|
|
/// | uuid::Uuid | UUID |
|
2015-05-18 03:27:39 +00:00
|
|
|
///
|
|
|
|
/// # Nullability
|
|
|
|
///
|
|
|
|
/// In addition to the types listed above, `ToSql` is implemented for
|
|
|
|
/// `Option<T>` where `T` implements `ToSql`. An `Option<T>` represents a
|
|
|
|
/// nullable Postgres value.
|
2015-03-31 06:22:31 +00:00
|
|
|
pub trait ToSql: fmt::Debug {
|
2015-02-15 23:31:07 +00:00
|
|
|
/// Converts the value of `self` into the binary format of the specified
|
|
|
|
/// Postgres `Type`, writing it to `out`.
|
2015-01-22 06:31:04 +00:00
|
|
|
///
|
2015-02-15 23:11:15 +00:00
|
|
|
/// The caller of this method is responsible for ensuring that this type
|
|
|
|
/// is compatible with the Postgres `Type`.
|
|
|
|
///
|
|
|
|
/// The return value indicates if this value should be represented as
|
|
|
|
/// `NULL`. If this is the case, implementations **must not** write
|
|
|
|
/// anything to `out`.
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: ?Sized>(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) -> Result<IsNull>
|
2015-02-26 17:02:32 +00:00
|
|
|
where Self: Sized, W: Write;
|
2015-02-15 23:11:15 +00:00
|
|
|
|
|
|
|
/// Determines if a value of this type can be converted to the specified
|
|
|
|
/// Postgres `Type`.
|
|
|
|
fn accepts(ty: &Type) -> bool where Self: Sized;
|
|
|
|
|
|
|
|
/// An adaptor method used internally by Rust-Postgres.
|
|
|
|
///
|
|
|
|
/// *All* implementations of this method should be generated by the
|
|
|
|
/// `to_sql_checked!()` macro.
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo)
|
|
|
|
-> Result<IsNull>;
|
2013-10-31 02:55:25 +00:00
|
|
|
}
|
|
|
|
|
2015-08-01 01:25:41 +00:00
|
|
|
impl<'a, T> ToSql for &'a T where T: ToSql {
|
2015-11-13 04:55:29 +00:00
|
|
|
to_sql_checked!();
|
2015-08-01 01:25:41 +00:00
|
|
|
|
|
|
|
fn to_sql<W: Write + ?Sized>(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) -> Result<IsNull> {
|
|
|
|
(*self).to_sql(ty, out, ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn accepts(ty: &Type) -> bool { T::accepts(ty) }
|
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl<T: ToSql> ToSql for Option<T> {
|
|
|
|
to_sql_checked!();
|
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, ty: &Type, out: &mut W, ctx: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-02-15 23:11:15 +00:00
|
|
|
match *self {
|
2015-05-22 05:28:51 +00:00
|
|
|
Some(ref val) => val.to_sql(ty, out, ctx),
|
2015-02-15 23:11:15 +00:00
|
|
|
None => Ok(IsNull::Yes),
|
|
|
|
}
|
2013-12-07 23:39:44 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
fn accepts(ty: &Type) -> bool {
|
|
|
|
<T as ToSql>::accepts(ty)
|
2014-03-15 06:01:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl ToSql for bool {
|
|
|
|
to_sql_checked!();
|
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-02-15 23:11:15 +00:00
|
|
|
try!(w.write_u8(*self as u8));
|
|
|
|
Ok(IsNull::No)
|
2013-12-08 03:13:21 +00:00
|
|
|
}
|
2015-02-15 23:11:15 +00:00
|
|
|
|
|
|
|
accepts!(Type::Bool);
|
2013-12-08 03:13:21 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl<'a> ToSql for &'a [u8] {
|
2015-11-13 04:55:29 +00:00
|
|
|
to_sql_checked!();
|
2013-10-31 02:55:25 +00:00
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-02-15 23:11:15 +00:00
|
|
|
try!(w.write_all(*self));
|
|
|
|
Ok(IsNull::No)
|
2014-12-14 19:39:26 +00:00
|
|
|
}
|
2015-02-15 23:11:15 +00:00
|
|
|
|
|
|
|
accepts!(Type::Bytea);
|
2014-12-14 19:39:26 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl ToSql for Vec<u8> {
|
|
|
|
to_sql_checked!();
|
2014-12-15 00:43:17 +00:00
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, ty: &Type, w: &mut W, ctx: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
|
|
|
<&[u8] as ToSql>::to_sql(&&**self, ty, w, ctx)
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
fn accepts(ty: &Type) -> bool {
|
|
|
|
<&[u8] as ToSql>::accepts(ty)
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
|
|
|
}
|
2014-12-14 23:07:48 +00:00
|
|
|
|
2014-10-26 03:24:08 +00:00
|
|
|
impl<'a> ToSql for &'a str {
|
2015-11-13 04:55:29 +00:00
|
|
|
to_sql_checked!();
|
2015-02-15 23:11:15 +00:00
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-02-15 23:11:15 +00:00
|
|
|
try!(w.write_all(self.as_bytes()));
|
|
|
|
Ok(IsNull::No)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn accepts(ty: &Type) -> bool {
|
2014-12-15 00:43:17 +00:00
|
|
|
match *ty {
|
2015-02-15 23:11:15 +00:00
|
|
|
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => true,
|
|
|
|
Type::Other(ref u) if u.name() == "citext" => true,
|
|
|
|
_ => false,
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
2013-08-28 04:36:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl ToSql for String {
|
|
|
|
to_sql_checked!();
|
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, ty: &Type, w: &mut W, ctx: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
|
|
|
<&str as ToSql>::to_sql(&&**self, ty, w, ctx)
|
2015-02-15 23:11:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn accepts(ty: &Type) -> bool {
|
|
|
|
<&str as ToSql>::accepts(ty)
|
2014-12-15 00:43:17 +00:00
|
|
|
}
|
|
|
|
}
|
2013-09-02 19:42:24 +00:00
|
|
|
|
2015-05-02 22:55:53 +00:00
|
|
|
impl ToSql for i8 {
|
|
|
|
to_sql_checked!();
|
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-05-02 22:55:53 +00:00
|
|
|
try!(w.write_i8(*self));
|
|
|
|
Ok(IsNull::No)
|
|
|
|
}
|
|
|
|
|
|
|
|
accepts!(Type::Char);
|
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
macro_rules! to_primitive {
|
|
|
|
($t:ty, $f:ident, $($expected:pat),+) => {
|
|
|
|
impl ToSql for $t {
|
|
|
|
to_sql_checked!();
|
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-02-26 17:02:32 +00:00
|
|
|
try!(w.$f::<BigEndian>(*self));
|
2015-02-15 23:11:15 +00:00
|
|
|
Ok(IsNull::No)
|
|
|
|
}
|
|
|
|
|
|
|
|
accepts!($($expected),+);
|
|
|
|
}
|
2013-09-02 19:42:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-26 17:02:32 +00:00
|
|
|
to_primitive!(i16, write_i16, Type::Int2);
|
|
|
|
to_primitive!(i32, write_i32, Type::Int4);
|
|
|
|
to_primitive!(u32, write_u32, Type::Oid);
|
|
|
|
to_primitive!(i64, write_i64, Type::Int8);
|
|
|
|
to_primitive!(f32, write_f32, Type::Float4);
|
|
|
|
to_primitive!(f64, write_f64, Type::Float8);
|
2014-12-19 18:43:42 +00:00
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
impl ToSql for HashMap<String, Option<String>> {
|
|
|
|
to_sql_checked!();
|
2013-12-05 05:20:48 +00:00
|
|
|
|
2015-05-22 05:28:51 +00:00
|
|
|
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W, _: &SessionInfo)
|
|
|
|
-> Result<IsNull> {
|
2015-06-02 03:28:23 +00:00
|
|
|
try!(w.write_i32::<BigEndian>(try!(downcast(self.len()))));
|
2013-12-05 05:20:48 +00:00
|
|
|
|
2015-05-02 22:55:53 +00:00
|
|
|
for (key, val) in self {
|
2015-06-02 03:28:23 +00:00
|
|
|
try!(w.write_i32::<BigEndian>(try!(downcast(key.len()))));
|
2015-02-15 23:11:15 +00:00
|
|
|
try!(w.write_all(key.as_bytes()));
|
2013-12-05 05:20:48 +00:00
|
|
|
|
|
|
|
match *val {
|
|
|
|
Some(ref val) => {
|
2015-06-02 03:28:23 +00:00
|
|
|
try!(w.write_i32::<BigEndian>(try!(downcast(val.len()))));
|
2015-02-15 23:11:15 +00:00
|
|
|
try!(w.write_all(val.as_bytes()));
|
2013-12-05 05:20:48 +00:00
|
|
|
}
|
2015-02-26 17:02:32 +00:00
|
|
|
None => try!(w.write_i32::<BigEndian>(-1))
|
2013-12-05 05:20:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
Ok(IsNull::No)
|
2013-12-05 05:20:48 +00:00
|
|
|
}
|
2014-03-13 06:50:10 +00:00
|
|
|
|
2015-02-15 23:11:15 +00:00
|
|
|
fn accepts(ty: &Type) -> bool {
|
2014-03-13 06:50:10 +00:00
|
|
|
match *ty {
|
2015-02-15 23:11:15 +00:00
|
|
|
Type::Other(ref u) if u.name() == "hstore" => true,
|
|
|
|
_ => false,
|
2014-03-13 06:50:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-06-02 03:28:23 +00:00
|
|
|
|
|
|
|
fn downcast(len: usize) -> Result<i32> {
|
|
|
|
if len > i32::max_value() as usize {
|
|
|
|
let err: Box<error::Error+Sync+Send> = "value too large to transmit".into();
|
|
|
|
Err(Error::Conversion(err))
|
|
|
|
} else {
|
|
|
|
Ok(len as i32)
|
|
|
|
}
|
|
|
|
}
|