Make Type an opaque type

This commit is contained in:
Steven Fackler 2017-07-09 00:02:45 -07:00
parent 561b46a7bf
commit bec973c776
19 changed files with 1500 additions and 1197 deletions

View File

@ -14,6 +14,7 @@ const PG_RANGE_H: &'static str = include_str!("pg_range.h");
struct Type { struct Type {
name: &'static str, name: &'static str,
variant: String, variant: String,
ident: String,
kind: &'static str, kind: &'static str,
element: u32, element: u32,
doc: String, doc: String,
@ -27,8 +28,8 @@ pub fn build(path: &Path) {
make_header(&mut file); make_header(&mut file);
make_enum(&mut file, &types); make_enum(&mut file, &types);
make_display_impl(&mut file);
make_impl(&mut file, &types); make_impl(&mut file, &types);
make_consts(&mut file, &types);
} }
fn parse_ranges() -> BTreeMap<u32, u32> { fn parse_ranges() -> BTreeMap<u32, u32> {
@ -69,14 +70,10 @@ fn parse_types(ranges: &BTreeMap<u32, u32>) -> BTreeMap<u32, Type> {
let name = split[5]; let name = split[5];
let variant = match name { let ident = range_vector_re.replace(name, "_$1");
"anyarray" => "AnyArray".to_owned(), let ident = array_re.replace(&ident, "$1_array");
name => { let variant = snake_to_camel(&ident);
let variant = range_vector_re.replace(name, "_$1"); let ident = ident.to_ascii_uppercase();
let variant = array_re.replace(&variant, "$1_array");
snake_to_camel(&variant)
}
};
let kind = split[11]; let kind = split[11];
@ -106,11 +103,12 @@ fn parse_types(ranges: &BTreeMap<u32, u32>) -> BTreeMap<u32, Type> {
let doc = String::from_utf8(doc).unwrap(); let doc = String::from_utf8(doc).unwrap();
let type_ = Type { let type_ = Type {
name: name, name,
variant: variant, variant,
kind: kind, ident,
element: element, kind,
doc: doc, element,
doc,
}; };
types.insert(oid, type_); types.insert(oid, type_);
@ -123,10 +121,17 @@ fn make_header(w: &mut BufWriter<File>) {
write!( write!(
w, w,
"// Autogenerated file - DO NOT EDIT "// Autogenerated file - DO NOT EDIT
use std::fmt; use std::sync::Arc;
use types::{{Oid, Kind, Other}}; use types::{{Type, Oid, Kind}};
#[derive(PartialEq, Eq, Debug)]
pub struct Other {{
pub name: String,
pub oid: Oid,
pub kind: Kind,
pub schema: String,
}}
" "
).unwrap(); ).unwrap();
} }
@ -134,55 +139,34 @@ use types::{{Oid, Kind, Other}};
fn make_enum(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) { fn make_enum(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
write!( write!(
w, w,
"/// A Postgres type. "
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
pub enum Type {{ pub enum Inner {{"
"
).unwrap(); ).unwrap();
for type_ in types.values() { for type_ in types.values() {
write!( write!(
w, w,
" /// {} "
{}, {},",
",
type_.doc,
type_.variant type_.variant
).unwrap(); ).unwrap();
} }
write!( write!(
w, w,
r" /// An unknown type. r"
Other(Other), Other(Arc<Other>),
}} }}
" "
).unwrap(); ).unwrap();
} }
fn make_display_impl(w: &mut BufWriter<File>) {
write!(w,
r#"impl fmt::Display for Type {{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {{
match self.schema() {{
"public" | "pg_catalog" => {{}}
schema => write!(fmt, "{{}}.", schema)?,
}}
fmt.write_str(self.name())
}}
}}
"#,
).unwrap();
}
fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) { fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
write!(w, write!(w,
"impl Type {{ "impl Inner {{
/// Returns the `Type` corresponding to the provided `Oid` if it pub fn from_oid(oid: Oid) -> Option<Inner> {{
/// corresponds to a built-in type.
pub fn from_oid(oid: Oid) -> Option<Type> {{
match oid {{ match oid {{
", ",
).unwrap(); ).unwrap();
@ -190,7 +174,7 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
for (oid, type_) in types { for (oid, type_) in types {
write!( write!(
w, w,
" {} => Some(Type::{}), " {} => Some(Inner::{}),
", ",
oid, oid,
type_.variant type_.variant
@ -202,7 +186,6 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
}} }}
}} }}
/// Returns the OID of the `Type`.
pub fn oid(&self) -> Oid {{ pub fn oid(&self) -> Oid {{
match *self {{ match *self {{
", ",
@ -212,7 +195,7 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
for (oid, type_) in types { for (oid, type_) in types {
write!( write!(
w, w,
" Type::{} => {}, " Inner::{} => {},
", ",
type_.variant, type_.variant,
oid oid
@ -220,11 +203,10 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
} }
write!(w, write!(w,
" Type::Other(ref u) => u.oid(), " Inner::Other(ref u) => u.oid,
}} }}
}} }}
/// Returns the kind of this type.
pub fn kind(&self) -> &Kind {{ pub fn kind(&self) -> &Kind {{
match *self {{ match *self {{
", ",
@ -233,14 +215,14 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
for type_ in types.values() { for type_ in types.values() {
let kind = match type_.kind { let kind = match type_.kind {
"P" => "Pseudo".to_owned(), "P" => "Pseudo".to_owned(),
"A" => format!("Array(Type::{})", types[&type_.element].variant), "A" => format!("Array(Type(Inner::{}))", types[&type_.element].variant),
"R" => format!("Range(Type::{})", types[&type_.element].variant), "R" => format!("Range(Type(Inner::{}))", types[&type_.element].variant),
_ => "Simple".to_owned(), _ => "Simple".to_owned(),
}; };
write!( write!(
w, w,
" Type::{} => {{ " Inner::{} => {{
const V: &'static Kind = &Kind::{}; const V: &'static Kind = &Kind::{};
V V
}} }}
@ -251,19 +233,10 @@ fn make_impl(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
} }
write!(w, write!(w,
r#" Type::Other(ref u) => u.kind(), r#" Inner::Other(ref u) => &u.kind,
}} }}
}} }}
/// Returns the schema of this type.
pub fn schema(&self) -> &str {{
match *self {{
Type::Other(ref u) => u.schema(),
_ => "pg_catalog",
}}
}}
/// Returns the name of this type.
pub fn name(&self) -> &str {{ pub fn name(&self) -> &str {{
match *self {{ match *self {{
"#, "#,
@ -272,7 +245,7 @@ r#" Type::Other(ref u) => u.kind(),
for type_ in types.values() { for type_ in types.values() {
write!( write!(
w, w,
r#" Type::{} => "{}", r#" Inner::{} => "{}",
"#, "#,
type_.variant, type_.variant,
type_.name type_.name
@ -281,10 +254,34 @@ r#" Type::Other(ref u) => u.kind(),
write!( write!(
w, w,
" Type::Other(ref u) => u.name(), " Inner::Other(ref u) => &u.name,
}} }}
}} }}
}} }}
" "
).unwrap(); ).unwrap();
} }
fn make_consts(w: &mut BufWriter<File>, types: &BTreeMap<u32, Type>) {
write!(w,
"pub mod consts {{
use types::Type;
use types::type_gen::Inner;
",
).unwrap();
for type_ in types.values() {
write!(w,
"
/// {docs}
pub const {ident}: Type = Type(Inner::{variant});
",
docs = type_.doc,
ident = type_.ident,
variant = type_.variant).unwrap();
}
write!(w,
"}}"
).unwrap();
}

View File

@ -4,7 +4,7 @@ use postgres_protocol::types;
use self::bit_vec::BitVec; use self::bit_vec::BitVec;
use std::error::Error; use std::error::Error;
use types::{FromSql, ToSql, IsNull, Type}; use types::{FromSql, ToSql, IsNull, Type, BIT, VARBIT};
impl FromSql for BitVec { impl FromSql for BitVec {
fn from_sql(_: &Type, raw: &[u8]) -> Result<BitVec, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<BitVec, Box<Error + Sync + Send>> {
@ -17,7 +17,7 @@ impl FromSql for BitVec {
Ok(bitvec) Ok(bitvec)
} }
accepts!(Type::Bit, Type::Varbit); accepts!(BIT, VARBIT);
} }
impl ToSql for BitVec { impl ToSql for BitVec {
@ -26,6 +26,6 @@ impl ToSql for BitVec {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Bit, Type::Varbit); accepts!(BIT, VARBIT);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -5,7 +5,7 @@ use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, Utc,
FixedOffset}; FixedOffset};
use std::error::Error; use std::error::Error;
use types::{FromSql, ToSql, IsNull, Type}; use types::{FromSql, ToSql, IsNull, Type, TIMESTAMP, TIMESTAMPTZ, DATE, TIME};
fn base() -> NaiveDateTime { fn base() -> NaiveDateTime {
NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0) NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0)
@ -17,7 +17,7 @@ impl FromSql for NaiveDateTime {
Ok(base() + Duration::microseconds(t)) Ok(base() + Duration::microseconds(t))
} }
accepts!(Type::Timestamp); accepts!(TIMESTAMP);
} }
impl ToSql for NaiveDateTime { impl ToSql for NaiveDateTime {
@ -30,7 +30,7 @@ impl ToSql for NaiveDateTime {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Timestamp); accepts!(TIMESTAMP);
to_sql_checked!(); to_sql_checked!();
} }
@ -40,7 +40,7 @@ impl FromSql for DateTime<Utc> {
Ok(DateTime::from_utc(naive, Utc)) Ok(DateTime::from_utc(naive, Utc))
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
} }
impl ToSql for DateTime<Utc> { impl ToSql for DateTime<Utc> {
@ -48,7 +48,7 @@ impl ToSql for DateTime<Utc> {
self.naive_utc().to_sql(type_, w) self.naive_utc().to_sql(type_, w)
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
to_sql_checked!(); to_sql_checked!();
} }
@ -58,7 +58,7 @@ impl FromSql for DateTime<Local> {
Ok(utc.with_timezone(&Local)) Ok(utc.with_timezone(&Local))
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
} }
impl ToSql for DateTime<Local> { impl ToSql for DateTime<Local> {
@ -70,7 +70,7 @@ impl ToSql for DateTime<Local> {
self.with_timezone(&Utc).to_sql(type_, w) self.with_timezone(&Utc).to_sql(type_, w)
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
to_sql_checked!(); to_sql_checked!();
} }
@ -83,7 +83,7 @@ impl FromSql for DateTime<FixedOffset> {
Ok(utc.with_timezone(&FixedOffset::east(0))) Ok(utc.with_timezone(&FixedOffset::east(0)))
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
} }
impl ToSql for DateTime<FixedOffset> { impl ToSql for DateTime<FixedOffset> {
@ -91,7 +91,7 @@ impl ToSql for DateTime<FixedOffset> {
self.with_timezone(&Utc).to_sql(type_, w) self.with_timezone(&Utc).to_sql(type_, w)
} }
accepts!(Type::Timestamptz); accepts!(TIMESTAMPTZ);
to_sql_checked!(); to_sql_checked!();
} }
@ -101,7 +101,7 @@ impl FromSql for NaiveDate {
Ok(base().date() + Duration::days(jd as i64)) Ok(base().date() + Duration::days(jd as i64))
} }
accepts!(Type::Date); accepts!(DATE);
} }
impl ToSql for NaiveDate { impl ToSql for NaiveDate {
@ -115,7 +115,7 @@ impl ToSql for NaiveDate {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Date); accepts!(DATE);
to_sql_checked!(); to_sql_checked!();
} }
@ -125,7 +125,7 @@ impl FromSql for NaiveTime {
Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec)) Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec))
} }
accepts!(Type::Time); accepts!(TIME);
} }
impl ToSql for NaiveTime { impl ToSql for NaiveTime {
@ -139,6 +139,6 @@ impl ToSql for NaiveTime {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Time); accepts!(TIME);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -4,7 +4,7 @@ use self::eui48::MacAddress;
use std::error::Error; use std::error::Error;
use postgres_protocol::types; use postgres_protocol::types;
use types::{FromSql, ToSql, Type, IsNull}; use types::{FromSql, ToSql, Type, IsNull, MACADDR};
impl FromSql for MacAddress { impl FromSql for MacAddress {
fn from_sql(_: &Type, raw: &[u8]) -> Result<MacAddress, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<MacAddress, Box<Error + Sync + Send>> {
@ -12,7 +12,7 @@ impl FromSql for MacAddress {
Ok(MacAddress::new(bytes)) Ok(MacAddress::new(bytes))
} }
accepts!(Type::Macaddr); accepts!(MACADDR);
} }
impl ToSql for MacAddress { impl ToSql for MacAddress {
@ -23,6 +23,6 @@ impl ToSql for MacAddress {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Macaddr); accepts!(MACADDR);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -5,7 +5,7 @@ use self::geo::{Bbox, LineString, Point};
use std::error::Error; use std::error::Error;
use fallible_iterator::FallibleIterator; use fallible_iterator::FallibleIterator;
use types::{FromSql, ToSql, IsNull, Type}; use types::{FromSql, ToSql, IsNull, Type, POINT, BOX, PATH};
impl FromSql for Point<f64> { impl FromSql for Point<f64> {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
@ -13,7 +13,7 @@ impl FromSql for Point<f64> {
Ok(Point::new(point.x(), point.y())) Ok(Point::new(point.x(), point.y()))
} }
accepts!(Type::Point); accepts!(POINT);
} }
impl ToSql for Point<f64> { impl ToSql for Point<f64> {
@ -22,7 +22,7 @@ impl ToSql for Point<f64> {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Point); accepts!(POINT);
to_sql_checked!(); to_sql_checked!();
} }
@ -37,7 +37,7 @@ impl FromSql for Bbox<f64> {
}) })
} }
accepts!(Type::Box); accepts!(BOX);
} }
impl ToSql for Bbox<f64> { impl ToSql for Bbox<f64> {
@ -46,7 +46,7 @@ impl ToSql for Bbox<f64> {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Box); accepts!(BOX);
to_sql_checked!(); to_sql_checked!();
} }
@ -57,7 +57,7 @@ impl FromSql for LineString<f64> {
Ok(LineString(points)) Ok(LineString(points))
} }
accepts!(Type::Path); accepts!(PATH);
} }
impl ToSql for LineString<f64> { impl ToSql for LineString<f64> {
@ -67,6 +67,6 @@ impl ToSql for LineString<f64> {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Path); accepts!(PATH);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -6,11 +6,13 @@ use std::error::Error;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use types::type_gen::{Inner, Other};
#[doc(inline)] #[doc(inline)]
pub use postgres_protocol::Oid; pub use postgres_protocol::Oid;
pub use self::type_gen::Type; pub use types::type_gen::consts::*;
pub use self::special::{Date, Timestamp}; pub use types::special::{Date, Timestamp};
/// Generates a simple implementation of `ToSql::accepts` which accepts the /// Generates a simple implementation of `ToSql::accepts` which accepts the
/// types passed to it. /// types passed to it.
@ -81,6 +83,62 @@ mod geo;
mod special; mod special;
mod type_gen; mod type_gen;
/// A Postgres type.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct Type(Inner);
impl fmt::Display for Type {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.schema() {
"public" | "pg_catalog" => {}
schema => write!(fmt, "{}.", schema)?,
}
fmt.write_str(self.name())
}
}
impl Type {
// WARNING: this is not considered public API
#[doc(hidden)]
pub fn _new(name: String, oid: Oid, kind: Kind, schema: String) -> Type {
Type(Inner::Other(Arc::new(Other {
name: name,
oid: oid,
kind: kind,
schema: schema,
})))
}
/// Returns the `Type` corresponding to the provided `Oid` if it
/// corresponds to a built-in type.
pub fn from_oid(oid: Oid) -> Option<Type> {
Inner::from_oid(oid).map(Type)
}
/// Returns the OID of the `Type`.
pub fn oid(&self) -> Oid {
self.0.oid()
}
/// Returns the kind of this type.
pub fn kind(&self) -> &Kind {
self.0.kind()
}
/// Returns the schema of this type.
pub fn schema(&self) -> &str {
match self.0 {
Inner::Other(ref u) => &u.schema,
_ => "pg_catalog",
}
}
/// Returns the name of this type.
pub fn name(&self) -> &str {
self.0.name()
}
}
/// Represents the kind of a Postgres type. /// Represents the kind of a Postgres type.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Kind { pub enum Kind {
@ -131,63 +189,6 @@ impl Field {
} }
} }
/// Information about an unknown type.
#[derive(PartialEq, Eq, Clone)]
pub struct Other(Arc<OtherInner>);
impl fmt::Debug for Other {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Other")
.field("name", &self.0.name)
.field("oid", &self.0.oid)
.field("kind", &self.0.kind)
.field("schema", &self.0.schema)
.finish()
}
}
#[derive(PartialEq, Eq)]
struct OtherInner {
name: String,
oid: Oid,
kind: Kind,
schema: String,
}
impl Other {
#[doc(hidden)]
pub fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other {
Other(Arc::new(OtherInner {
name: name,
oid: oid,
kind: kind,
schema: schema,
}))
}
}
impl Other {
/// The name of the type.
pub fn name(&self) -> &str {
&self.0.name
}
/// The OID of this type.
pub fn oid(&self) -> Oid {
self.0.oid
}
/// The kind of this type.
pub fn kind(&self) -> &Kind {
&self.0.kind
}
/// The schema of this type.
pub fn schema(&self) -> &str {
&self.0.schema
}
}
/// An error indicating that a `NULL` Postgres value was passed to a `FromSql` /// An error indicating that a `NULL` Postgres value was passed to a `FromSql`
/// implementation that does not support `NULL` values. /// implementation that does not support `NULL` values.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -365,7 +366,7 @@ impl FromSql for Vec<u8> {
Ok(types::bytea_from_sql(raw).to_owned()) Ok(types::bytea_from_sql(raw).to_owned())
} }
accepts!(Type::Bytea); accepts!(BYTEA);
} }
impl FromSql for String { impl FromSql for String {
@ -375,8 +376,8 @@ impl FromSql for String {
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
match *ty { match *ty {
Type::Varchar | Type::Text | Type::Bpchar | Type::Name | Type::Unknown => true, VARCHAR | TEXT | BPCHAR | NAME | UNKNOWN => true,
Type::Other(ref u) if u.name() == "citext" => true, ref ty if ty.name() == "citext" => true,
_ => false, _ => false,
} }
} }
@ -396,14 +397,14 @@ macro_rules! simple_from {
} }
} }
simple_from!(bool, bool_from_sql, Type::Bool); simple_from!(bool, bool_from_sql, BOOL);
simple_from!(i8, char_from_sql, Type::Char); simple_from!(i8, char_from_sql, CHAR);
simple_from!(i16, int2_from_sql, Type::Int2); simple_from!(i16, int2_from_sql, INT2);
simple_from!(i32, int4_from_sql, Type::Int4); simple_from!(i32, int4_from_sql, INT4);
simple_from!(u32, oid_from_sql, Type::Oid); simple_from!(u32, oid_from_sql, OID);
simple_from!(i64, int8_from_sql, Type::Int8); simple_from!(i64, int8_from_sql, INT8);
simple_from!(f32, float4_from_sql, Type::Float4); simple_from!(f32, float4_from_sql, FLOAT4);
simple_from!(f64, float8_from_sql, Type::Float8); simple_from!(f64, float8_from_sql, FLOAT8);
impl FromSql for HashMap<String, Option<String>> { impl FromSql for HashMap<String, Option<String>> {
fn from_sql( fn from_sql(
@ -416,10 +417,7 @@ impl FromSql for HashMap<String, Option<String>> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
match *ty { ty.name() == "hstore"
Type::Other(ref u) if u.name() == "hstore" => true,
_ => false,
}
} }
} }
@ -589,7 +587,7 @@ impl<'a> ToSql for &'a [u8] {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Bytea); accepts!(BYTEA);
to_sql_checked!(); to_sql_checked!();
} }
@ -626,8 +624,8 @@ impl<'a> ToSql for &'a str {
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
match *ty { match *ty {
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => true, VARCHAR | TEXT | BPCHAR | NAME | UNKNOWN => true,
Type::Other(ref u) if u.name() == "citext" => true, ref ty if ty.name() == "citext" => true,
_ => false, _ => false,
} }
} }
@ -665,14 +663,14 @@ macro_rules! simple_to {
} }
} }
simple_to!(bool, bool_to_sql, Type::Bool); simple_to!(bool, bool_to_sql, BOOL);
simple_to!(i8, char_to_sql, Type::Char); simple_to!(i8, char_to_sql, CHAR);
simple_to!(i16, int2_to_sql, Type::Int2); simple_to!(i16, int2_to_sql, INT2);
simple_to!(i32, int4_to_sql, Type::Int4); simple_to!(i32, int4_to_sql, INT4);
simple_to!(u32, oid_to_sql, Type::Oid); simple_to!(u32, oid_to_sql, OID);
simple_to!(i64, int8_to_sql, Type::Int8); simple_to!(i64, int8_to_sql, INT8);
simple_to!(f32, float4_to_sql, Type::Float4); simple_to!(f32, float4_to_sql, FLOAT4);
simple_to!(f64, float8_to_sql, Type::Float8); simple_to!(f64, float8_to_sql, FLOAT8);
impl ToSql for HashMap<String, Option<String>> { impl ToSql for HashMap<String, Option<String>> {
fn to_sql(&self, _: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> { fn to_sql(&self, _: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
@ -684,10 +682,7 @@ impl ToSql for HashMap<String, Option<String>> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
match *ty { ty.name() == "hstore"
Type::Other(ref u) if u.name() == "hstore" => true,
_ => false,
}
} }
to_sql_checked!(); to_sql_checked!();

View File

@ -4,11 +4,11 @@ use self::rustc_serialize::json;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::error::Error; use std::error::Error;
use types::{FromSql, ToSql, IsNull, Type}; use types::{FromSql, ToSql, IsNull, Type, JSON, JSONB};
impl FromSql for json::Json { impl FromSql for json::Json {
fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<json::Json, Box<Error + Sync + Send>> { fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<json::Json, Box<Error + Sync + Send>> {
if let Type::Jsonb = *ty { if *ty == JSONB {
let mut b = [0; 1]; let mut b = [0; 1];
raw.read_exact(&mut b)?; raw.read_exact(&mut b)?;
// We only support version 1 of the jsonb binary format // We only support version 1 of the jsonb binary format
@ -19,18 +19,18 @@ impl FromSql for json::Json {
json::Json::from_reader(&mut raw).map_err(Into::into) json::Json::from_reader(&mut raw).map_err(Into::into)
} }
accepts!(Type::Json, Type::Jsonb); accepts!(JSON, JSONB);
} }
impl ToSql for json::Json { impl ToSql for json::Json {
fn to_sql(&self, ty: &Type, mut out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> { fn to_sql(&self, ty: &Type, mut out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
if let Type::Jsonb = *ty { if *ty == JSONB {
out.push(1); out.push(1);
} }
write!(out, "{}", self)?; write!(out, "{}", self)?;
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Json, Type::Jsonb); accepts!(JSON, JSONB);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -4,11 +4,11 @@ use self::serde_json::Value;
use std::error::Error; use std::error::Error;
use std::io::{Read, Write}; use std::io::{Read, Write};
use types::{FromSql, ToSql, IsNull, Type}; use types::{FromSql, ToSql, IsNull, Type, JSON, JSONB};
impl FromSql for Value { impl FromSql for Value {
fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> { fn from_sql(ty: &Type, mut raw: &[u8]) -> Result<Value, Box<Error + Sync + Send>> {
if let Type::Jsonb = *ty { if *ty == JSONB {
let mut b = [0; 1]; let mut b = [0; 1];
raw.read_exact(&mut b)?; raw.read_exact(&mut b)?;
// We only support version 1 of the jsonb binary format // We only support version 1 of the jsonb binary format
@ -19,18 +19,18 @@ impl FromSql for Value {
serde_json::de::from_reader(raw).map_err(Into::into) serde_json::de::from_reader(raw).map_err(Into::into)
} }
accepts!(Type::Json, Type::Jsonb); accepts!(JSON, JSONB);
} }
impl ToSql for Value { impl ToSql for Value {
fn to_sql(&self, ty: &Type, mut out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> { fn to_sql(&self, ty: &Type, mut out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
if let Type::Jsonb = *ty { if *ty == JSONB {
out.push(1); out.push(1);
} }
write!(out, "{}", self)?; write!(out, "{}", self)?;
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Json, Type::Jsonb); accepts!(JSON, JSONB);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -2,7 +2,7 @@ use postgres_protocol::types;
use std::{i32, i64}; use std::{i32, i64};
use std::error::Error; use std::error::Error;
use types::{Type, FromSql, ToSql, IsNull}; use types::{Type, FromSql, ToSql, IsNull, DATE, TIMESTAMP, TIMESTAMPTZ};
/// A wrapper that can be used to represent infinity with `Type::Date` types. /// A wrapper that can be used to represent infinity with `Type::Date` types.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -25,7 +25,7 @@ impl<T: FromSql> FromSql for Date<T> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
*ty == Type::Date && T::accepts(ty) *ty == DATE && T::accepts(ty)
} }
} }
impl<T: ToSql> ToSql for Date<T> { impl<T: ToSql> ToSql for Date<T> {
@ -41,7 +41,7 @@ impl<T: ToSql> ToSql for Date<T> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
*ty == Type::Date && T::accepts(ty) *ty == DATE && T::accepts(ty)
} }
to_sql_checked!(); to_sql_checked!();
@ -69,7 +69,10 @@ impl<T: FromSql> FromSql for Timestamp<T> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
(*ty == Type::Timestamp || *ty == Type::Timestamptz) && T::accepts(ty) match *ty {
TIMESTAMP | TIMESTAMPTZ if T::accepts(ty) => true,
_ => false
}
} }
} }
@ -86,7 +89,10 @@ impl<T: ToSql> ToSql for Timestamp<T> {
} }
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
(*ty == Type::Timestamp || *ty == Type::Timestamptz) && T::accepts(ty) match *ty {
TIMESTAMP | TIMESTAMPTZ if T::accepts(ty) => true,
_ => false
}
} }
to_sql_checked!(); to_sql_checked!();

View File

@ -4,7 +4,7 @@ use self::time::Timespec;
use std::error::Error; use std::error::Error;
use postgres_protocol::types; use postgres_protocol::types;
use types::{Type, FromSql, ToSql, IsNull}; use types::{Type, FromSql, ToSql, IsNull, TIMESTAMP, TIMESTAMPTZ};
const USEC_PER_SEC: i64 = 1_000_000; const USEC_PER_SEC: i64 = 1_000_000;
const NSEC_PER_USEC: i64 = 1_000; const NSEC_PER_USEC: i64 = 1_000;
@ -26,7 +26,7 @@ impl FromSql for Timespec {
Ok(Timespec::new(sec, (usec * NSEC_PER_USEC) as i32)) Ok(Timespec::new(sec, (usec * NSEC_PER_USEC) as i32))
} }
accepts!(Type::Timestamp, Type::Timestamptz); accepts!(TIMESTAMP, TIMESTAMPTZ);
} }
impl ToSql for Timespec { impl ToSql for Timespec {
@ -36,6 +36,6 @@ impl ToSql for Timespec {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Timestamp, Type::Timestamptz); accepts!(TIMESTAMP, TIMESTAMPTZ);
to_sql_checked!(); to_sql_checked!();
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ use postgres_protocol::types;
use self::uuid::Uuid; use self::uuid::Uuid;
use std::error::Error; use std::error::Error;
use types::{FromSql, ToSql, Type, IsNull}; use types::{FromSql, ToSql, Type, IsNull, UUID};
impl FromSql for Uuid { impl FromSql for Uuid {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Uuid, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<Uuid, Box<Error + Sync + Send>> {
@ -12,7 +12,7 @@ impl FromSql for Uuid {
Ok(Uuid::from_bytes(&bytes).unwrap()) Ok(Uuid::from_bytes(&bytes).unwrap())
} }
accepts!(Type::Uuid); accepts!(UUID);
} }
impl ToSql for Uuid { impl ToSql for Uuid {
@ -21,6 +21,6 @@ impl ToSql for Uuid {
Ok(IsNull::No) Ok(IsNull::No)
} }
accepts!(Type::Uuid); accepts!(UUID);
to_sql_checked!(); to_sql_checked!();
} }

View File

@ -101,7 +101,7 @@ use priv_io::MessageStream;
use rows::{Rows, LazyRows}; use rows::{Rows, LazyRows};
use stmt::{Statement, Column}; use stmt::{Statement, Column};
use transaction::{Transaction, IsolationLevel}; use transaction::{Transaction, IsolationLevel};
use types::{IsNull, Kind, Type, Oid, Other, ToSql, FromSql, Field}; use types::{IsNull, Kind, Type, Oid, ToSql, FromSql, Field, OID, NAME, CHAR};
#[doc(inline)] #[doc(inline)]
pub use postgres_shared::CancelData; pub use postgres_shared::CancelData;
@ -236,7 +236,7 @@ struct InnerConnection {
notice_handler: Box<HandleNotice>, notice_handler: Box<HandleNotice>,
notifications: VecDeque<Notification>, notifications: VecDeque<Notification>,
cancel_data: CancelData, cancel_data: CancelData,
unknown_types: HashMap<Oid, Other>, unknown_types: HashMap<Oid, Type>,
cached_statements: HashMap<String, Arc<StatementInfo>>, cached_statements: HashMap<String, Arc<StatementInfo>>,
parameters: HashMap<String, String>, parameters: HashMap<String, String>,
next_stmt_id: u32, next_stmt_id: u32,
@ -745,12 +745,12 @@ impl InnerConnection {
} }
if let Some(ty) = self.unknown_types.get(&oid) { if let Some(ty) = self.unknown_types.get(&oid) {
return Ok(Type::Other(ty.clone())); return Ok(ty.clone());
} }
let ty = self.read_type(oid)?; let ty = self.read_type(oid)?;
self.unknown_types.insert(oid, ty.clone()); self.unknown_types.insert(oid, ty.clone());
Ok(Type::Other(ty)) Ok(ty)
} }
fn setup_typeinfo_query(&mut self) -> Result<()> { fn setup_typeinfo_query(&mut self) -> Result<()> {
@ -790,13 +790,13 @@ impl InnerConnection {
} }
#[allow(if_not_else)] #[allow(if_not_else)]
fn read_type(&mut self, oid: Oid) -> Result<Other> { fn read_type(&mut self, oid: Oid) -> Result<Type> {
self.setup_typeinfo_query()?; self.setup_typeinfo_query()?;
self.raw_execute( self.raw_execute(
TYPEINFO_QUERY, TYPEINFO_QUERY,
"", "",
0, 0,
&[Type::Oid], &[OID],
&[&oid], &[&oid],
)?; )?;
let mut row = None; let mut row = None;
@ -805,24 +805,24 @@ impl InnerConnection {
let get_raw = |i: usize| row.as_ref().and_then(|r| r.get(i)); let get_raw = |i: usize| row.as_ref().and_then(|r| r.get(i));
let (name, type_, elem_oid, rngsubtype, basetype, schema, relid) = { let (name, type_, elem_oid, rngsubtype, basetype, schema, relid) = {
let name = String::from_sql_nullable(&Type::Name, get_raw(0)).map_err( let name = String::from_sql_nullable(&NAME, get_raw(0)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let type_ = i8::from_sql_nullable(&Type::Char, get_raw(1)).map_err( let type_ = i8::from_sql_nullable(&CHAR, get_raw(1)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let elem_oid = Oid::from_sql_nullable(&Type::Oid, get_raw(2)).map_err( let elem_oid = Oid::from_sql_nullable(&OID, get_raw(2)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let rngsubtype = Option::<Oid>::from_sql_nullable(&Type::Oid, get_raw(3)) let rngsubtype = Option::<Oid>::from_sql_nullable(&OID, get_raw(3))
.map_err(Error::Conversion)?; .map_err(Error::Conversion)?;
let basetype = Oid::from_sql_nullable(&Type::Oid, get_raw(4)).map_err( let basetype = Oid::from_sql_nullable(&OID, get_raw(4)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let schema = String::from_sql_nullable(&Type::Name, get_raw(5)).map_err( let schema = String::from_sql_nullable(&NAME, get_raw(5)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let relid = Oid::from_sql_nullable(&Type::Oid, get_raw(6)).map_err( let relid = Oid::from_sql_nullable(&OID, get_raw(6)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
(name, type_, elem_oid, rngsubtype, basetype, schema, relid) (name, type_, elem_oid, rngsubtype, basetype, schema, relid)
@ -845,7 +845,7 @@ impl InnerConnection {
} }
}; };
Ok(Other::new(name, oid, kind, schema)) Ok(Type::_new(name, oid, kind, schema))
} }
fn setup_typeinfo_enum_query(&mut self) -> Result<()> { fn setup_typeinfo_enum_query(&mut self) -> Result<()> {
@ -884,7 +884,7 @@ impl InnerConnection {
TYPEINFO_ENUM_QUERY, TYPEINFO_ENUM_QUERY,
"", "",
0, 0,
&[Type::Oid], &[OID],
&[&oid], &[&oid],
)?; )?;
let mut rows = vec![]; let mut rows = vec![];
@ -892,7 +892,7 @@ impl InnerConnection {
let mut variants = vec![]; let mut variants = vec![];
for row in rows { for row in rows {
variants.push(String::from_sql_nullable(&Type::Name, row.get(0)).map_err( variants.push(String::from_sql_nullable(&NAME, row.get(0)).map_err(
Error::Conversion, Error::Conversion,
)?); )?);
} }
@ -925,7 +925,7 @@ impl InnerConnection {
TYPEINFO_COMPOSITE_QUERY, TYPEINFO_COMPOSITE_QUERY,
"", "",
0, 0,
&[Type::Oid], &[OID],
&[&relid], &[&relid],
)?; )?;
let mut rows = vec![]; let mut rows = vec![];
@ -934,10 +934,10 @@ impl InnerConnection {
let mut fields = vec![]; let mut fields = vec![];
for row in rows { for row in rows {
let (name, type_) = { let (name, type_) = {
let name = String::from_sql_nullable(&Type::Name, row.get(0)).map_err( let name = String::from_sql_nullable(&NAME, row.get(0)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
let type_ = Oid::from_sql_nullable(&Type::Oid, row.get(1)).map_err( let type_ = Oid::from_sql_nullable(&OID, row.get(1)).map_err(
Error::Conversion, Error::Conversion,
)?; )?;
(name, type_) (name, type_)
@ -1468,10 +1468,6 @@ fn err(fields: &mut ErrorFields) -> Error {
} }
} }
trait OtherNew {
fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other;
}
trait RowsNew { trait RowsNew {
fn new(stmt: &Statement, data: Vec<RowData>) -> Rows<'static>; fn new(stmt: &Statement, data: Vec<RowData>) -> Rows<'static>;
} }

View File

@ -1,8 +1,8 @@
//! Traits dealing with Postgres data types //! Traits dealing with Postgres data types
#[doc(inline)] #[doc(inline)]
pub use postgres_shared::types::{Oid, Type, Date, Timestamp, Kind, Field, Other, WasNull, // FIXME
WrongType, FromSql, IsNull, ToSql}; pub use postgres_shared::types::*;
#[doc(hidden)] #[doc(hidden)]
pub use postgres_shared::types::__to_sql_checked; pub use postgres_shared::types::__to_sql_checked;

View File

@ -14,7 +14,7 @@ use postgres::{HandleNotice, Connection, GenericConnection, TlsMode};
use postgres::transaction::{self, IsolationLevel}; use postgres::transaction::{self, IsolationLevel};
use postgres::error::{Error, ConnectError, DbError, SYNTAX_ERROR, QUERY_CANCELED, UNDEFINED_TABLE, use postgres::error::{Error, ConnectError, DbError, SYNTAX_ERROR, QUERY_CANCELED, UNDEFINED_TABLE,
INVALID_CATALOG_NAME, INVALID_PASSWORD, CARDINALITY_VIOLATION}; INVALID_CATALOG_NAME, INVALID_PASSWORD, CARDINALITY_VIOLATION};
use postgres::types::{Oid, Type, Kind, WrongType}; use postgres::types::{Oid, Type, Kind, WrongType, INT4, VARCHAR, FLOAT8};
use postgres::error::ErrorPosition::Normal; use postgres::error::ErrorPosition::Normal;
use postgres::rows::RowIndex; use postgres::rows::RowIndex;
use postgres::notification::Notification; use postgres::notification::Notification;
@ -574,7 +574,7 @@ fn test_param_types() {
TlsMode::None, TlsMode::None,
)); ));
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(), &[Type::Int4, Type::Varchar][..]); assert_eq!(stmt.param_types(), &[INT4, VARCHAR][..]);
} }
#[test] #[test]
@ -587,9 +587,9 @@ fn test_columns() {
let cols = stmt.columns(); let cols = stmt.columns();
assert_eq!(2, cols.len()); assert_eq!(2, cols.len());
assert_eq!(cols[0].name(), "a"); assert_eq!(cols[0].name(), "a");
assert_eq!(cols[0].type_(), &Type::Int4); assert_eq!(cols[0].type_(), &INT4);
assert_eq!(cols[1].name(), "b"); assert_eq!(cols[1].name(), "b");
assert_eq!(cols[1].type_(), &Type::Varchar); assert_eq!(cols[1].type_(), &VARCHAR);
} }
#[test] #[test]
@ -1277,13 +1277,9 @@ fn test_custom_range_element_type() {
&[], &[],
)); ));
let stmt = or_panic!(conn.prepare("SELECT $1::floatrange")); let stmt = or_panic!(conn.prepare("SELECT $1::floatrange"));
match &stmt.param_types()[0] { let ty = &stmt.param_types()[0];
&Type::Other(ref u) => { assert_eq!("floatrange", ty.name());
assert_eq!("floatrange", u.name()); assert_eq!(&Kind::Range(FLOAT8), ty.kind());
assert_eq!(&Kind::Range(Type::Float8), u.kind());
}
t => panic!("Unexpected type {:?}", t),
}
} }
#[test] #[test]

View File

@ -7,7 +7,7 @@ use std::result;
use postgres::{Connection, TlsMode}; use postgres::{Connection, TlsMode};
use postgres::error::Error; use postgres::error::Error;
use postgres::types::{ToSql, FromSql, WrongType, Type, IsNull, Kind}; use postgres::types::{ToSql, FromSql, WrongType, Type, IsNull, Kind, TEXT, INT4, NUMERIC};
#[cfg(feature = "with-bit-vec")] #[cfg(feature = "with-bit-vec")]
mod bit_vec; mod bit_vec;
@ -449,11 +449,11 @@ fn composite() {
match *type_.kind() { match *type_.kind() {
Kind::Composite(ref fields) => { Kind::Composite(ref fields) => {
assert_eq!(fields[0].name(), "name"); assert_eq!(fields[0].name(), "name");
assert_eq!(fields[0].type_(), &Type::Text); assert_eq!(fields[0].type_(), &TEXT);
assert_eq!(fields[1].name(), "supplier"); assert_eq!(fields[1].name(), "supplier");
assert_eq!(fields[1].type_(), &Type::Int4); assert_eq!(fields[1].type_(), &INT4);
assert_eq!(fields[2].name(), "price"); assert_eq!(fields[2].name(), "price");
assert_eq!(fields[2].type_(), &Type::Numeric); assert_eq!(fields[2].type_(), &NUMERIC);
} }
ref t => panic!("bad type {:?}", t), ref t => panic!("bad type {:?}", t),
} }

View File

@ -95,7 +95,7 @@ use stmt::{Statement, Column};
use stream::PostgresStream; use stream::PostgresStream;
use tls::Handshake; use tls::Handshake;
use transaction::Transaction; use transaction::Transaction;
use types::{Oid, Type, ToSql, IsNull, FromSql, Other, Kind, Field}; use types::{Oid, Type, ToSql, IsNull, FromSql, Kind, Field, NAME, CHAR, OID};
use rows::Row; use rows::Row;
pub mod error; pub mod error;
@ -173,7 +173,7 @@ struct InnerConnection {
close_receiver: Receiver<(u8, String)>, close_receiver: Receiver<(u8, String)>,
close_sender: Sender<(u8, String)>, close_sender: Sender<(u8, String)>,
parameters: HashMap<String, String>, parameters: HashMap<String, String>,
types: HashMap<Oid, Other>, types: HashMap<Oid, Type>,
notifications: VecDeque<Notification>, notifications: VecDeque<Notification>,
cancel_data: CancelData, cancel_data: CancelData,
has_typeinfo_query: bool, has_typeinfo_query: bool,
@ -661,53 +661,53 @@ impl Connection {
return Ok((type_, self)).into_future().boxed(); return Ok((type_, self)).into_future().boxed();
}; };
let other = self.0.types.get(&oid).map(Clone::clone); let ty = self.0.types.get(&oid).map(Clone::clone);
if let Some(other) = other { if let Some(ty) = ty {
return Ok((Type::Other(other), self)).into_future().boxed(); return Ok((ty, self)).into_future().boxed();
} }
self.get_unknown_type(oid) self.get_unknown_type(oid)
.map(move |(ty, mut c)| { .map(move |(ty, mut c)| {
c.0.types.insert(oid, ty.clone()); c.0.types.insert(oid, ty.clone());
(Type::Other(ty), c) (ty, c)
}) })
.boxed() .boxed()
} }
fn get_unknown_type(self, oid: Oid) -> BoxFuture<(Other, Connection), Error> { fn get_unknown_type(self, oid: Oid) -> BoxFuture<(Type, Connection), Error> {
self.setup_typeinfo_query() self.setup_typeinfo_query()
.and_then(move |c| { .and_then(move |c| {
c.raw_execute(TYPEINFO_QUERY, "", &[Type::Oid], &[&oid]) c.raw_execute(TYPEINFO_QUERY, "", &[OID], &[&oid])
}) })
.and_then(|c| c.read_rows().collect()) .and_then(|c| c.read_rows().collect())
.and_then(move |(r, c)| { .and_then(move |(r, c)| {
let get = |idx| r.get(0).and_then(|r| r.get(idx)); let get = |idx| r.get(0).and_then(|r| r.get(idx));
let name = match String::from_sql_nullable(&Type::Name, get(0)) { let name = match String::from_sql_nullable(&NAME, get(0)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let type_ = match i8::from_sql_nullable(&Type::Char, get(1)) { let type_ = match i8::from_sql_nullable(&CHAR, get(1)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let elem_oid = match Oid::from_sql_nullable(&Type::Oid, get(2)) { let elem_oid = match Oid::from_sql_nullable(&OID, get(2)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let rngsubtype = match Option::<Oid>::from_sql_nullable(&Type::Oid, get(3)) { let rngsubtype = match Option::<Oid>::from_sql_nullable(&OID, get(3)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let basetype = match Oid::from_sql_nullable(&Type::Oid, get(4)) { let basetype = match Oid::from_sql_nullable(&OID, get(4)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let schema = match String::from_sql_nullable(&Type::Name, get(5)) { let schema = match String::from_sql_nullable(&NAME, get(5)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let relid = match Oid::from_sql_nullable(&Type::Oid, get(6)) { let relid = match Oid::from_sql_nullable(&OID, get(6)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
@ -749,7 +749,7 @@ impl Connection {
}; };
Either::B(kind.map( Either::B(kind.map(
move |(k, c)| (Other::new(name, oid, k, schema), c), move |(k, c)| (Type::_new(name, oid, k, schema), c),
)) ))
}) })
.boxed() .boxed()
@ -802,13 +802,13 @@ impl Connection {
fn get_enum_variants(self, oid: Oid) -> BoxFuture<(Vec<String>, Connection), Error> { fn get_enum_variants(self, oid: Oid) -> BoxFuture<(Vec<String>, Connection), Error> {
self.setup_typeinfo_enum_query() self.setup_typeinfo_enum_query()
.and_then(move |c| { .and_then(move |c| {
c.raw_execute(TYPEINFO_ENUM_QUERY, "", &[Type::Oid], &[&oid]) c.raw_execute(TYPEINFO_ENUM_QUERY, "", &[OID], &[&oid])
}) })
.and_then(|c| c.read_rows().collect()) .and_then(|c| c.read_rows().collect())
.and_then(|(r, c)| { .and_then(|(r, c)| {
let mut variants = vec![]; let mut variants = vec![];
for row in r { for row in r {
let variant = match String::from_sql_nullable(&Type::Name, row.get(0)) { let variant = match String::from_sql_nullable(&NAME, row.get(0)) {
Ok(v) => v, Ok(v) => v,
Err(e) => return Err(Error::Conversion(e, c)), Err(e) => return Err(Error::Conversion(e, c)),
}; };
@ -854,18 +854,18 @@ impl Connection {
fn get_composite_fields(self, oid: Oid) -> BoxFuture<(Vec<Field>, Connection), Error> { fn get_composite_fields(self, oid: Oid) -> BoxFuture<(Vec<Field>, Connection), Error> {
self.setup_typeinfo_composite_query() self.setup_typeinfo_composite_query()
.and_then(move |c| { .and_then(move |c| {
c.raw_execute(TYPEINFO_COMPOSITE_QUERY, "", &[Type::Oid], &[&oid]) c.raw_execute(TYPEINFO_COMPOSITE_QUERY, "", &[OID], &[&oid])
}) })
.and_then(|c| c.read_rows().collect()) .and_then(|c| c.read_rows().collect())
.and_then(|(r, c)| { .and_then(|(r, c)| {
futures::stream::iter(r.into_iter().map(Ok)).fold( futures::stream::iter(r.into_iter().map(Ok)).fold(
(vec![], c), (vec![], c),
|(mut fields, c), row| { |(mut fields, c), row| {
let name = match String::from_sql_nullable(&Type::Name, row.get(0)) { let name = match String::from_sql_nullable(&NAME, row.get(0)) {
Ok(name) => name, Ok(name) => name,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };
let oid = match Oid::from_sql_nullable(&Type::Oid, row.get(1)) { let oid = match Oid::from_sql_nullable(&OID, row.get(1)) {
Ok(oid) => oid, Ok(oid) => oid,
Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()), Err(e) => return Either::A(Err(Error::Conversion(e, c)).into_future()),
}; };

View File

@ -9,7 +9,7 @@ use super::*;
use error::{Error, ConnectError, INVALID_PASSWORD, INVALID_AUTHORIZATION_SPECIFICATION, use error::{Error, ConnectError, INVALID_PASSWORD, INVALID_AUTHORIZATION_SPECIFICATION,
QUERY_CANCELED}; QUERY_CANCELED};
use params::{ConnectParams, Host}; use params::{ConnectParams, Host};
use types::{ToSql, FromSql, Type, IsNull, Kind}; use types::{ToSql, FromSql, Type, IsNull, Kind, BYTEA, TEXT, INT4, NUMERIC};
#[test] #[test]
fn md5_user() { fn md5_user() {
@ -318,7 +318,7 @@ fn domain() {
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
match *ty.kind() { match *ty.kind() {
Kind::Domain(Type::Bytea) => ty.name() == "session_id", Kind::Domain(BYTEA) => ty.name() == "session_id",
_ => false, _ => false,
} }
} }
@ -385,11 +385,11 @@ fn composite() {
match *type_.kind() { match *type_.kind() {
Kind::Composite(ref fields) => { Kind::Composite(ref fields) => {
assert_eq!(fields[0].name(), "name"); assert_eq!(fields[0].name(), "name");
assert_eq!(fields[0].type_(), &Type::Text); assert_eq!(fields[0].type_(), &TEXT);
assert_eq!(fields[1].name(), "supplier"); assert_eq!(fields[1].name(), "supplier");
assert_eq!(fields[1].type_(), &Type::Int4); assert_eq!(fields[1].type_(), &INT4);
assert_eq!(fields[2].name(), "price"); assert_eq!(fields[2].name(), "price");
assert_eq!(fields[2].type_(), &Type::Numeric); assert_eq!(fields[2].type_(), &NUMERIC);
} }
ref t => panic!("bad type {:?}", t), ref t => panic!("bad type {:?}", t),
} }

View File

@ -1,8 +1,8 @@
//! Postgres types //! Postgres types
#[doc(inline)] #[doc(inline)]
pub use postgres_shared::types::{Oid, Type, Date, Timestamp, Kind, Field, Other, WasNull, // FIXME
WrongType, FromSql, IsNull, ToSql}; pub use postgres_shared::types::*;
#[doc(hidden)] #[doc(hidden)]
pub use postgres_shared::types::__to_sql_checked; pub use postgres_shared::types::__to_sql_checked;