Demangle PostgresType

This commit is contained in:
Steven Fackler 2014-11-03 21:29:16 -08:00
parent 167b9d0209
commit ad82d28d18
4 changed files with 149 additions and 148 deletions

View File

@ -9,7 +9,7 @@ use openssl::ssl::error;
use phf; use phf;
use Result; use Result;
use types::PostgresType; use types::Type;
macro_rules! make_errors( macro_rules! make_errors(
($($code:expr => $error:ident),+) => ( ($($code:expr => $error:ident),+) => (
@ -552,7 +552,7 @@ pub enum PostgresError {
}, },
/// An attempt was made to convert between incompatible Rust and Postgres /// An attempt was made to convert between incompatible Rust and Postgres
/// types /// types
PgWrongType(PostgresType), PgWrongType(Type),
/// An attempt was made to read from a column that does not exist /// An attempt was made to read from a column that does not exist
PgInvalidColumn, PgInvalidColumn,
/// A value was NULL but converted to a non-nullable Rust type /// A value was NULL but converted to a non-nullable Rust type

View File

@ -133,7 +133,8 @@ use message::{Bind,
Sync, Sync,
Terminate}; Terminate};
use message::{WriteMessage, ReadMessage}; use message::{WriteMessage, ReadMessage};
use types::{Oid, PostgresType, ToSql, FromSql, PgUnknownType}; #[doc(inline)]
pub use types::{Oid, Type, ToSql, FromSql};
#[macro_escape] #[macro_escape]
mod macros; mod macros;
@ -504,7 +505,7 @@ impl InnerConnection {
} }
fn raw_prepare(&mut self, query: &str) fn raw_prepare(&mut self, query: &str)
-> Result<(String, Vec<PostgresType>, Vec<ResultDescription>)> { -> Result<(String, Vec<Type>, Vec<ResultDescription>)> {
let stmt_name = format!("s{}", self.next_stmt_id); let stmt_name = format!("s{}", self.next_stmt_id);
self.next_stmt_id += 1; self.next_stmt_id += 1;
@ -531,7 +532,7 @@ impl InnerConnection {
let mut param_types: Vec<_> = match try_pg!(self.read_message()) { let mut param_types: Vec<_> = match try_pg!(self.read_message()) {
ParameterDescription { types } => { ParameterDescription { types } => {
types.iter().map(|ty| PostgresType::from_oid(*ty)).collect() types.iter().map(|ty| Type::from_oid(*ty)).collect()
} }
_ => bad_response!(self), _ => bad_response!(self),
}; };
@ -541,7 +542,7 @@ impl InnerConnection {
descriptions.into_iter().map(|RowDescriptionEntry { name, type_oid, .. }| { descriptions.into_iter().map(|RowDescriptionEntry { name, type_oid, .. }| {
ResultDescription { ResultDescription {
name: name, name: name,
ty: PostgresType::from_oid(type_oid) ty: Type::from_oid(type_oid)
} }
}).collect() }).collect()
} }
@ -618,9 +619,9 @@ impl InnerConnection {
} }
fn set_type_names<'a, I>(&mut self, mut it: I) -> Result<()> fn set_type_names<'a, I>(&mut self, mut it: I) -> Result<()>
where I: Iterator<&'a mut PostgresType> { where I: Iterator<&'a mut Type> {
for ty in it { for ty in it {
if let &PgUnknownType { oid, ref mut name } = ty { if let &Type::Unknown { oid, ref mut name } = ty {
*name = try!(self.get_type_name(oid)); *name = try!(self.get_type_name(oid));
} }
} }
@ -1111,7 +1112,7 @@ impl<'conn> Transaction<'conn> {
pub struct Statement<'conn> { pub struct Statement<'conn> {
conn: &'conn Connection, conn: &'conn Connection,
name: String, name: String,
param_types: Vec<PostgresType>, param_types: Vec<Type>,
result_desc: Vec<ResultDescription>, result_desc: Vec<ResultDescription>,
next_portal_id: Cell<uint>, next_portal_id: Cell<uint>,
finished: bool, finished: bool,
@ -1196,7 +1197,7 @@ impl<'conn> Statement<'conn> {
} }
/// Returns a slice containing the expected parameter types. /// Returns a slice containing the expected parameter types.
pub fn param_types(&self) -> &[PostgresType] { pub fn param_types(&self) -> &[Type] {
self.param_types[] self.param_types[]
} }
@ -1300,7 +1301,7 @@ pub struct ResultDescription {
/// The name of the column /// The name of the column
pub name: String, pub name: String,
/// The type of the data in the column /// The type of the data in the column
pub ty: PostgresType pub ty: Type
} }
/// An iterator over the resulting rows of a query. /// An iterator over the resulting rows of a query.
@ -1538,7 +1539,7 @@ impl<'trans, 'stmt> Iterator<Result<Row<'stmt>>> for LazyRows<'trans, 'stmt> {
pub struct CopyInStatement<'a> { pub struct CopyInStatement<'a> {
conn: &'a Connection, conn: &'a Connection,
name: String, name: String,
column_types: Vec<PostgresType>, column_types: Vec<Type>,
finished: bool, finished: bool,
} }
@ -1559,7 +1560,7 @@ impl<'a> CopyInStatement<'a> {
} }
/// Returns a slice containing the expected column types. /// Returns a slice containing the expected column types.
pub fn column_types(&self) -> &[PostgresType] { pub fn column_types(&self) -> &[Type] {
self.column_types[] self.column_types[]
} }

View File

@ -2,7 +2,6 @@
#![macro_escape] #![macro_escape]
use serialize::json; use serialize::json;
use serialize::json::Json;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{AsRefReader, MemWriter, BufReader}; use std::io::{AsRefReader, MemWriter, BufReader};
use std::io::util::LimitReader; use std::io::util::LimitReader;
@ -75,13 +74,13 @@ macro_rules! make_postgres_type(
($(#[$doc:meta] $oid:ident => $variant:ident $(member $member:ident)*),+) => ( ($(#[$doc:meta] $oid:ident => $variant:ident $(member $member:ident)*),+) => (
/// A Postgres type /// A Postgres type
#[deriving(PartialEq, Eq, Clone, Show)] #[deriving(PartialEq, Eq, Clone, Show)]
pub enum PostgresType { pub enum Type {
$( $(
#[$doc] #[$doc]
$variant, $variant,
)+ )+
/// An unknown type /// An unknown type
PgUnknownType { Unknown {
/// The name of the type /// The name of the type
pub name: String, pub name: String,
/// The OID of the type /// The OID of the type
@ -89,28 +88,28 @@ macro_rules! make_postgres_type(
} }
} }
impl PostgresType { impl Type {
#[doc(hidden)] #[doc(hidden)]
pub fn from_oid(oid: Oid) -> PostgresType { pub fn from_oid(oid: Oid) -> Type {
match oid { match oid {
$($oid => $variant,)+ $($oid => Type::$variant,)+
// We have to load an empty string now, it'll get filled in later // We have to load an empty string now, it'll get filled in later
oid => PgUnknownType { name: String::new(), oid: oid } oid => Type::Unknown { name: String::new(), oid: oid }
} }
} }
#[doc(hidden)] #[doc(hidden)]
pub fn to_oid(&self) -> Oid { pub fn to_oid(&self) -> Oid {
match *self { match *self {
$($variant => $oid,)+ $(Type::$variant => $oid,)+
PgUnknownType { oid, .. } => oid Type::Unknown { oid, .. } => oid
} }
} }
fn member_type(&self) -> PostgresType { fn member_type(&self) -> Type {
match *self { match *self {
$( $(
$($variant => $member,)* $(Type::$variant => Type::$member,)*
)+ )+
_ => unreachable!() _ => unreachable!()
} }
@ -121,81 +120,81 @@ macro_rules! make_postgres_type(
make_postgres_type!( make_postgres_type!(
#[doc="BOOL"] #[doc="BOOL"]
BOOLOID => PgBool, BOOLOID => Bool,
#[doc="BYTEA"] #[doc="BYTEA"]
BYTEAOID => PgByteA, BYTEAOID => ByteA,
#[doc="\"char\""] #[doc="\"char\""]
CHAROID => PgChar, CHAROID => Char,
#[doc="NAME"] #[doc="NAME"]
NAMEOID => PgName, NAMEOID => Name,
#[doc="INT8/BIGINT"] #[doc="INT8/BIGINT"]
INT8OID => PgInt8, INT8OID => Int8,
#[doc="INT2/SMALLINT"] #[doc="INT2/SMALLINT"]
INT2OID => PgInt2, INT2OID => Int2,
#[doc="INT4/INT"] #[doc="INT4/INT"]
INT4OID => PgInt4, INT4OID => Int4,
#[doc="TEXT"] #[doc="TEXT"]
TEXTOID => PgText, TEXTOID => Text,
#[doc="JSON"] #[doc="JSON"]
JSONOID => PgJson, JSONOID => Json,
#[doc="JSON[]"] #[doc="JSON[]"]
JSONARRAYOID => PgJsonArray member PgJson, JSONARRAYOID => JsonArray member Json,
#[doc="FLOAT4/REAL"] #[doc="FLOAT4/REAL"]
FLOAT4OID => PgFloat4, FLOAT4OID => Float4,
#[doc="FLOAT8/DOUBLE PRECISION"] #[doc="FLOAT8/DOUBLE PRECISION"]
FLOAT8OID => PgFloat8, FLOAT8OID => Float8,
#[doc="BOOL[]"] #[doc="BOOL[]"]
BOOLARRAYOID => PgBoolArray member PgBool, BOOLARRAYOID => BoolArray member Bool,
#[doc="BYTEA[]"] #[doc="BYTEA[]"]
BYTEAARRAYOID => PgByteAArray member PgByteA, BYTEAARRAYOID => ByteAArray member ByteA,
#[doc="\"char\"[]"] #[doc="\"char\"[]"]
CHARARRAYOID => PgCharArray member PgChar, CHARARRAYOID => CharArray member Char,
#[doc="NAME[]"] #[doc="NAME[]"]
NAMEARRAYOID => PgNameArray member PgName, NAMEARRAYOID => NameArray member Name,
#[doc="INT2[]"] #[doc="INT2[]"]
INT2ARRAYOID => PgInt2Array member PgInt2, INT2ARRAYOID => Int2Array member Int2,
#[doc="INT4[]"] #[doc="INT4[]"]
INT4ARRAYOID => PgInt4Array member PgInt4, INT4ARRAYOID => Int4Array member Int4,
#[doc="TEXT[]"] #[doc="TEXT[]"]
TEXTARRAYOID => PgTextArray member PgText, TEXTARRAYOID => TextArray member Text,
#[doc="CHAR(n)[]"] #[doc="CHAR(n)[]"]
BPCHARARRAYOID => PgCharNArray member PgCharN, BPCHARARRAYOID => CharNArray member CharN,
#[doc="VARCHAR[]"] #[doc="VARCHAR[]"]
VARCHARARRAYOID => PgVarcharArray member PgVarchar, VARCHARARRAYOID => VarcharArray member Varchar,
#[doc="INT8[]"] #[doc="INT8[]"]
INT8ARRAYOID => PgInt8Array member PgInt8, INT8ARRAYOID => Int8Array member Int8,
#[doc="FLOAT4[]"] #[doc="FLOAT4[]"]
FLOAT4ARRAYOID => PgFloat4Array member PgFloat4, FLOAT4ARRAYOID => Float4Array member Float4,
#[doc="FLOAT8[]"] #[doc="FLOAT8[]"]
FLAOT8ARRAYOID => PgFloat8Array member PgFloat8, FLAOT8ARRAYOID => Float8Array member Float8,
#[doc="TIMESTAMP"] #[doc="TIMESTAMP"]
TIMESTAMPOID => PgTimestamp, TIMESTAMPOID => Timestamp,
#[doc="TIMESTAMP[]"] #[doc="TIMESTAMP[]"]
TIMESTAMPARRAYOID => PgTimestampArray member PgTimestamp, TIMESTAMPARRAYOID => TimestampArray member Timestamp,
#[doc="TIMESTAMP WITH TIME ZONE"] #[doc="TIMESTAMP WITH TIME ZONE"]
TIMESTAMPZOID => PgTimestampTZ, TIMESTAMPZOID => TimestampTZ,
#[doc="TIMESTAMP WITH TIME ZONE[]"] #[doc="TIMESTAMP WITH TIME ZONE[]"]
TIMESTAMPZARRAYOID => PgTimestampTZArray member PgTimestampTZ, TIMESTAMPZARRAYOID => TimestampTZArray member TimestampTZ,
#[doc="CHAR(n)/CHARACTER(n)"] #[doc="CHAR(n)/CHARACTER(n)"]
BPCHAROID => PgCharN, BPCHAROID => CharN,
#[doc="VARCHAR/CHARACTER VARYING"] #[doc="VARCHAR/CHARACTER VARYING"]
VARCHAROID => PgVarchar, VARCHAROID => Varchar,
#[doc="INT4RANGE"] #[doc="INT4RANGE"]
INT4RANGEOID => PgInt4Range, INT4RANGEOID => Int4Range,
#[doc="INT4RANGE[]"] #[doc="INT4RANGE[]"]
INT4RANGEARRAYOID => PgInt4RangeArray member PgInt4Range, INT4RANGEARRAYOID => Int4RangeArray member Int4Range,
#[doc="TSRANGE"] #[doc="TSRANGE"]
TSRANGEOID => PgTsRange, TSRANGEOID => TsRange,
#[doc="TSRANGE[]"] #[doc="TSRANGE[]"]
TSRANGEARRAYOID => PgTsRangeArray member PgTsRange, TSRANGEARRAYOID => TsRangeArray member TsRange,
#[doc="TSTZRANGE"] #[doc="TSTZRANGE"]
TSTZRANGEOID => PgTstzRange, TSTZRANGEOID => TstzRange,
#[doc="TSTZRANGE[]"] #[doc="TSTZRANGE[]"]
TSTZRANGEARRAYOID => PgTstzRangeArray member PgTstzRange, TSTZRANGEARRAYOID => TstzRangeArray member TstzRange,
#[doc="INT8RANGE"] #[doc="INT8RANGE"]
INT8RANGEOID => PgInt8Range, INT8RANGEOID => Int8Range,
#[doc="INT8RANGE[]"] #[doc="INT8RANGE[]"]
INT8RANGEARRAYOID => PgInt8RangeArray member PgInt8Range INT8RANGEARRAYOID => Int8RangeArray member Int8Range
) )
macro_rules! check_types( macro_rules! check_types(
@ -212,7 +211,7 @@ pub trait FromSql {
/// Creates a new value of this type from a buffer of Postgres data. /// Creates a new value of this type from a buffer of Postgres data.
/// ///
/// If the value was `NULL`, the buffer will be `None`. /// If the value was `NULL`, the buffer will be `None`.
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) -> Result<Self>; fn from_sql(ty: &Type, raw: &Option<Vec<u8>>) -> Result<Self>;
} }
#[doc(hidden)] #[doc(hidden)]
@ -321,8 +320,8 @@ from_range_impl!(i32)
from_range_impl!(i64) from_range_impl!(i64)
from_range_impl!(Timespec) from_range_impl!(Timespec)
impl RawFromSql for Json { impl RawFromSql for json::Json {
fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<Json> { fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<json::Json> {
json::from_reader(raw).map_err(|_| PgBadData) json::from_reader(raw).map_err(|_| PgBadData)
} }
} }
@ -330,7 +329,7 @@ impl RawFromSql for Json {
macro_rules! from_map_impl( macro_rules! from_map_impl(
($($expected:pat)|+, $t:ty, $blk:expr) => ( ($($expected:pat)|+, $t:ty, $blk:expr) => (
impl FromSql for Option<$t> { impl FromSql for Option<$t> {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
-> Result<Option<$t>> { -> Result<Option<$t>> {
check_types!($($expected)|+, ty) check_types!($($expected)|+, ty)
match *raw { match *raw {
@ -341,7 +340,7 @@ macro_rules! from_map_impl(
} }
impl FromSql for $t { impl FromSql for $t {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
-> Result<$t> { -> Result<$t> {
// FIXME when you can specify Self types properly // FIXME when you can specify Self types properly
let ret: Result<Option<$t>> = FromSql::from_sql(ty, raw); let ret: Result<Option<$t>> = FromSql::from_sql(ty, raw);
@ -364,21 +363,21 @@ macro_rules! from_raw_from_impl(
) )
) )
from_raw_from_impl!(PgBool, bool) from_raw_from_impl!(Bool, bool)
from_raw_from_impl!(PgByteA, Vec<u8>) from_raw_from_impl!(ByteA, Vec<u8>)
from_raw_from_impl!(PgVarchar | PgText | PgCharN | PgName, String) from_raw_from_impl!(Varchar | Text | CharN | Name, String)
from_raw_from_impl!(PgChar, i8) from_raw_from_impl!(Char, i8)
from_raw_from_impl!(PgInt2, i16) from_raw_from_impl!(Int2, i16)
from_raw_from_impl!(PgInt4, i32) from_raw_from_impl!(Int4, i32)
from_raw_from_impl!(PgInt8, i64) from_raw_from_impl!(Int8, i64)
from_raw_from_impl!(PgFloat4, f32) from_raw_from_impl!(Float4, f32)
from_raw_from_impl!(PgFloat8, f64) from_raw_from_impl!(Float8, f64)
from_raw_from_impl!(PgJson, Json) from_raw_from_impl!(Json, json::Json)
from_raw_from_impl!(PgTimestamp | PgTimestampTZ, Timespec) from_raw_from_impl!(Timestamp | TimestampTZ, Timespec)
from_raw_from_impl!(PgInt4Range, Range<i32>) from_raw_from_impl!(Int4Range, Range<i32>)
from_raw_from_impl!(PgInt8Range, Range<i64>) from_raw_from_impl!(Int8Range, Range<i64>)
from_raw_from_impl!(PgTsRange | PgTstzRange, Range<Timespec>) from_raw_from_impl!(TsRange | TstzRange, Range<Timespec>)
macro_rules! from_array_impl( macro_rules! from_array_impl(
($($oid:ident)|+, $t:ty) => ( ($($oid:ident)|+, $t:ty) => (
@ -415,26 +414,26 @@ macro_rules! from_array_impl(
) )
) )
from_array_impl!(PgBoolArray, bool) from_array_impl!(BoolArray, bool)
from_array_impl!(PgByteAArray, Vec<u8>) from_array_impl!(ByteAArray, Vec<u8>)
from_array_impl!(PgCharArray, i8) from_array_impl!(CharArray, i8)
from_array_impl!(PgInt2Array, i16) from_array_impl!(Int2Array, i16)
from_array_impl!(PgInt4Array, i32) from_array_impl!(Int4Array, i32)
from_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, String) from_array_impl!(TextArray | CharNArray | VarcharArray | NameArray, String)
from_array_impl!(PgInt8Array, i64) from_array_impl!(Int8Array, i64)
from_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec) from_array_impl!(TimestampArray | TimestampTZArray, Timespec)
from_array_impl!(PgJsonArray, Json) from_array_impl!(JsonArray, json::Json)
from_array_impl!(PgFloat4Array, f32) from_array_impl!(Float4Array, f32)
from_array_impl!(PgFloat8Array, f64) from_array_impl!(Float8Array, f64)
from_array_impl!(PgInt4RangeArray, Range<i32>) from_array_impl!(Int4RangeArray, Range<i32>)
from_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>) from_array_impl!(TsRangeArray | TstzRangeArray, Range<Timespec>)
from_array_impl!(PgInt8RangeArray, Range<i64>) from_array_impl!(Int8RangeArray, Range<i64>)
impl FromSql for Option<HashMap<String, Option<String>>> { impl FromSql for Option<HashMap<String, Option<String>>> {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
-> Result<Option<HashMap<String, Option<String>>>> { -> Result<Option<HashMap<String, Option<String>>>> {
match *ty { match *ty {
PgUnknownType { ref name, .. } if "hstore" == name[] => {} Type::Unknown { ref name, .. } if "hstore" == name[] => {}
_ => return Err(PgWrongType(ty.clone())) _ => return Err(PgWrongType(ty.clone()))
} }
@ -474,7 +473,7 @@ impl FromSql for Option<HashMap<String, Option<String>>> {
} }
impl FromSql for HashMap<String, Option<String>> { impl FromSql for HashMap<String, Option<String>> {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
-> Result<HashMap<String, Option<String>>> { -> Result<HashMap<String, Option<String>>> {
// FIXME when you can specify Self types properly // FIXME when you can specify Self types properly
let ret: Result<Option<HashMap<String, Option<String>>>> = let ret: Result<Option<HashMap<String, Option<String>>>> =
@ -491,7 +490,7 @@ impl FromSql for HashMap<String, Option<String>> {
pub trait ToSql { pub trait ToSql {
/// Converts the value of `self` into the binary format appropriate for the /// Converts the value of `self` into the binary format appropriate for the
/// Postgres backend. /// Postgres backend.
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>>; fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>>;
} }
#[doc(hidden)] #[doc(hidden)]
@ -594,7 +593,7 @@ to_range_impl!(i32)
to_range_impl!(i64) to_range_impl!(i64)
to_range_impl!(Timespec) to_range_impl!(Timespec)
impl RawToSql for Json { impl RawToSql for json::Json {
fn raw_to_sql<W: Writer>(&self, raw: &mut W) -> Result<()> { fn raw_to_sql<W: Writer>(&self, raw: &mut W) -> Result<()> {
Ok(try_pg!(self.to_writer(raw as &mut Writer))) Ok(try_pg!(self.to_writer(raw as &mut Writer)))
} }
@ -603,7 +602,7 @@ impl RawToSql for Json {
macro_rules! to_option_impl( macro_rules! to_option_impl(
($($oid:pat)|+, $t:ty) => ( ($($oid:pat)|+, $t:ty) => (
impl ToSql for Option<$t> { impl ToSql for Option<$t> {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!($($oid)|+, ty) check_types!($($oid)|+, ty)
match *self { match *self {
@ -618,7 +617,7 @@ macro_rules! to_option_impl(
macro_rules! to_option_impl_lifetime( macro_rules! to_option_impl_lifetime(
($($oid:pat)|+, $t:ty) => ( ($($oid:pat)|+, $t:ty) => (
impl<'a> ToSql for Option<$t> { impl<'a> ToSql for Option<$t> {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!($($oid)|+, ty) check_types!($($oid)|+, ty)
match *self { match *self {
@ -633,7 +632,7 @@ macro_rules! to_option_impl_lifetime(
macro_rules! to_raw_to_impl( macro_rules! to_raw_to_impl(
($($oid:ident)|+, $t:ty) => ( ($($oid:ident)|+, $t:ty) => (
impl ToSql for $t { impl ToSql for $t {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!($($oid)|+, ty) check_types!($($oid)|+, ty)
let mut writer = MemWriter::new(); let mut writer = MemWriter::new();
@ -646,44 +645,44 @@ macro_rules! to_raw_to_impl(
) )
) )
to_raw_to_impl!(PgBool, bool) to_raw_to_impl!(Bool, bool)
to_raw_to_impl!(PgByteA, Vec<u8>) to_raw_to_impl!(ByteA, Vec<u8>)
to_raw_to_impl!(PgVarchar | PgText | PgCharN | PgName, String) to_raw_to_impl!(Varchar | Text | CharN | Name, String)
to_raw_to_impl!(PgJson, Json) to_raw_to_impl!(Json, json::Json)
to_raw_to_impl!(PgChar, i8) to_raw_to_impl!(Char, i8)
to_raw_to_impl!(PgInt2, i16) to_raw_to_impl!(Int2, i16)
to_raw_to_impl!(PgInt4, i32) to_raw_to_impl!(Int4, i32)
to_raw_to_impl!(PgInt8, i64) to_raw_to_impl!(Int8, i64)
to_raw_to_impl!(PgFloat4, f32) to_raw_to_impl!(Float4, f32)
to_raw_to_impl!(PgFloat8, f64) to_raw_to_impl!(Float8, f64)
to_raw_to_impl!(PgInt4Range, Range<i32>) to_raw_to_impl!(Int4Range, Range<i32>)
to_raw_to_impl!(PgInt8Range, Range<i64>) to_raw_to_impl!(Int8Range, Range<i64>)
to_raw_to_impl!(PgTsRange | PgTstzRange, Range<Timespec>) to_raw_to_impl!(TsRange | TstzRange, Range<Timespec>)
impl<'a> ToSql for &'a str { impl<'a> ToSql for &'a str {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!(PgVarchar | PgText | PgCharN | PgName, ty) check_types!(Varchar | Text | CharN | Name, ty)
Ok(Some(self.as_bytes().to_vec())) Ok(Some(self.as_bytes().to_vec()))
} }
} }
to_option_impl_lifetime!(PgVarchar | PgText | PgCharN | PgName, &'a str) to_option_impl_lifetime!(Varchar | Text | CharN | Name, &'a str)
impl<'a> ToSql for &'a [u8] { impl<'a> ToSql for &'a [u8] {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!(PgByteA, ty) check_types!(ByteA, ty)
Ok(Some(self.to_vec())) Ok(Some(self.to_vec()))
} }
} }
to_option_impl_lifetime!(PgByteA, &'a [u8]) to_option_impl_lifetime!(ByteA, &'a [u8])
to_raw_to_impl!(PgTimestamp | PgTimestampTZ, Timespec) to_raw_to_impl!(Timestamp | TimestampTZ, Timespec)
macro_rules! to_array_impl( macro_rules! to_array_impl(
($($oid:ident)|+, $t:ty) => ( ($($oid:ident)|+, $t:ty) => (
impl ToSql for ArrayBase<Option<$t>> { impl ToSql for ArrayBase<Option<$t>> {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
check_types!($($oid)|+, ty) check_types!($($oid)|+, ty)
let mut buf = MemWriter::new(); let mut buf = MemWriter::new();
@ -717,25 +716,25 @@ macro_rules! to_array_impl(
) )
) )
to_array_impl!(PgBoolArray, bool) to_array_impl!(BoolArray, bool)
to_array_impl!(PgByteAArray, Vec<u8>) to_array_impl!(ByteAArray, Vec<u8>)
to_array_impl!(PgCharArray, i8) to_array_impl!(CharArray, i8)
to_array_impl!(PgInt2Array, i16) to_array_impl!(Int2Array, i16)
to_array_impl!(PgInt4Array, i32) to_array_impl!(Int4Array, i32)
to_array_impl!(PgInt8Array, i64) to_array_impl!(Int8Array, i64)
to_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, String) to_array_impl!(TextArray | CharNArray | VarcharArray | NameArray, String)
to_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec) to_array_impl!(TimestampArray | TimestampTZArray, Timespec)
to_array_impl!(PgFloat4Array, f32) to_array_impl!(Float4Array, f32)
to_array_impl!(PgFloat8Array, f64) to_array_impl!(Float8Array, f64)
to_array_impl!(PgInt4RangeArray, Range<i32>) to_array_impl!(Int4RangeArray, Range<i32>)
to_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>) to_array_impl!(TsRangeArray | TstzRangeArray, Range<Timespec>)
to_array_impl!(PgInt8RangeArray, Range<i64>) to_array_impl!(Int8RangeArray, Range<i64>)
to_array_impl!(PgJsonArray, Json) to_array_impl!(JsonArray, json::Json)
impl ToSql for HashMap<String, Option<String>> { impl ToSql for HashMap<String, Option<String>> {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
match *ty { match *ty {
PgUnknownType { ref name, .. } if "hstore" == name[] => {} Type::Unknown { ref name, .. } if "hstore" == name[] => {}
_ => return Err(PgWrongType(ty.clone())) _ => return Err(PgWrongType(ty.clone()))
} }
@ -761,9 +760,9 @@ impl ToSql for HashMap<String, Option<String>> {
} }
impl ToSql for Option<HashMap<String, Option<String>>> { impl ToSql for Option<HashMap<String, Option<String>>> {
fn to_sql(&self, ty: &PostgresType) -> Result<Option<Vec<u8>>> { fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
match *ty { match *ty {
PgUnknownType { ref name, .. } if "hstore" == name[] => {} Type::Unknown { ref name, .. } if "hstore" == name[] => {}
_ => return Err(PgWrongType(ty.clone())) _ => return Err(PgWrongType(ty.clone()))
} }

View File

@ -18,7 +18,9 @@ use postgres::{NoticeHandler,
ResultDescription, ResultDescription,
RequireSsl, RequireSsl,
PreferSsl, PreferSsl,
NoSsl}; NoSsl,
Type,
ToSql};
use postgres::error::{PgConnectDbError, use postgres::error::{PgConnectDbError,
PgDbError, PgDbError,
PgWrongConnection, PgWrongConnection,
@ -36,7 +38,6 @@ use postgres::error::{PgConnectDbError,
InvalidCatalogName, InvalidCatalogName,
PgWrongTransaction, PgWrongTransaction,
CardinalityViolation}; CardinalityViolation};
use postgres::types::{PgInt4, PgVarchar, ToSql};
macro_rules! or_panic( macro_rules! or_panic(
($e:expr) => ( ($e:expr) => (
@ -441,7 +442,7 @@ fn test_lazy_query_wrong_conn() {
fn test_param_types() { fn test_param_types() {
let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &NoSsl)); let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &NoSsl));
let stmt = or_panic!(conn.prepare("SELECT $1::INT, $2::VARCHAR")); let stmt = or_panic!(conn.prepare("SELECT $1::INT, $2::VARCHAR"));
assert_eq!(stmt.param_types(), [PgInt4, PgVarchar][]); assert_eq!(stmt.param_types(), [Type::Int4, Type::Varchar][]);
} }
#[test] #[test]
@ -449,8 +450,8 @@ fn test_result_descriptions() {
let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &NoSsl)); let conn = or_panic!(Connection::connect("postgres://postgres@localhost", &NoSsl));
let stmt = or_panic!(conn.prepare("SELECT 1::INT as a, 'hi'::VARCHAR as b")); let stmt = or_panic!(conn.prepare("SELECT 1::INT as a, 'hi'::VARCHAR as b"));
assert!(stmt.result_descriptions() == assert!(stmt.result_descriptions() ==
[ResultDescription { name: "a".to_string(), ty: PgInt4}, [ResultDescription { name: "a".to_string(), ty: Type::Int4},
ResultDescription { name: "b".to_string(), ty: PgVarchar}]); ResultDescription { name: "b".to_string(), ty: Type::Varchar}]);
} }
#[test] #[test]
@ -762,7 +763,7 @@ fn test_copy_in_bad_type() {
let res = stmt.execute(data.iter().map(|r| r.iter().map(|&e| e))); let res = stmt.execute(data.iter().map(|r| r.iter().map(|&e| e)));
match res { match res {
Err(PgDbError(ref err)) if err.message[].contains("Unexpected type PgVarchar") => {} Err(PgDbError(ref err)) if err.message[].contains("Unexpected type Varchar") => {}
Err(err) => panic!("unexpected error {}", err), Err(err) => panic!("unexpected error {}", err),
_ => panic!("Expected error"), _ => panic!("Expected error"),
} }