Move errors to shared

This commit is contained in:
Steven Fackler 2016-12-20 16:07:45 -08:00
parent 1e8b375d67
commit 3b8fc56296
10 changed files with 64 additions and 30 deletions

View File

@ -9,7 +9,7 @@ mod sqlstate;
mod type_gen; mod type_gen;
fn main() { fn main() {
let path = Path::new("../src"); let path = Path::new("..");
sqlstate::build(path); sqlstate::build(path);
type_gen::build(path); type_gen::build(path);
} }

View File

@ -13,7 +13,7 @@ struct Code {
} }
pub fn build(path: &Path) { pub fn build(path: &Path) {
let mut file = BufWriter::new(File::create(path.join("error/sqlstate.rs")).unwrap()); let mut file = BufWriter::new(File::create(path.join("postgres-shared/src/error/sqlstate.rs")).unwrap());
let codes = parse_codes(); let codes = parse_codes();

View File

@ -20,7 +20,7 @@ struct Type {
} }
pub fn build(path: &Path) { pub fn build(path: &Path) {
let mut file = BufWriter::new(File::create(path.join("types/type_gen.rs")).unwrap()); let mut file = BufWriter::new(File::create(path.join("postgres/src/types/type_gen.rs")).unwrap());
let ranges = parse_ranges(); let ranges = parse_ranges();
let types = parse_types(&ranges); let types = parse_types(&ranges);

View File

@ -5,3 +5,6 @@ authors = ["Steven Fackler <sfackler@gmail.com>"]
[dependencies] [dependencies]
hex = "0.2" hex = "0.2"
fallible-iterator = "0.1.3"
phf = "=0.7.20"
postgres-protocol = "0.2"

View File

@ -6,10 +6,8 @@ use std::error;
use std::convert::From; use std::convert::From;
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::result;
pub use self::sqlstate::SqlState; pub use self::sqlstate::SqlState;
use {Result, DbErrorNew};
mod sqlstate; mod sqlstate;
@ -141,8 +139,9 @@ pub struct DbError {
_p: (), _p: (),
} }
impl DbErrorNew for DbError { impl DbError {
fn new_raw(fields: &mut ErrorFields) -> io::Result<DbError> { #[doc(hidden)]
pub fn new_raw(fields: &mut ErrorFields) -> io::Result<DbError> {
let mut severity = None; let mut severity = None;
let mut parsed_severity = None; let mut parsed_severity = None;
let mut code = None; let mut code = None;
@ -169,8 +168,18 @@ impl DbErrorNew for DbError {
b'M' => message = Some(field.value().to_owned()), b'M' => message = Some(field.value().to_owned()),
b'D' => detail = Some(field.value().to_owned()), b'D' => detail = Some(field.value().to_owned()),
b'H' => hint = Some(field.value().to_owned()), b'H' => hint = Some(field.value().to_owned()),
b'P' => normal_position = Some(try!(field.value().parse::<u32>().map_err(|_| ::bad_response()))), b'P' => {
b'p' => internal_position = Some(try!(field.value().parse::<u32>().map_err(|_| ::bad_response()))), normal_position = Some(try!(field.value().parse::<u32>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput,
"`P` field did not contain an integer")
})));
}
b'p' => {
internal_position = Some(try!(field.value().parse::<u32>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput,
"`p` field did not contain an integer")
})));
}
b'q' => internal_query = Some(field.value().to_owned()), b'q' => internal_query = Some(field.value().to_owned()),
b'W' => where_ = Some(field.value().to_owned()), b'W' => where_ = Some(field.value().to_owned()),
b's' => schema = Some(field.value().to_owned()), b's' => schema = Some(field.value().to_owned()),
@ -179,18 +188,32 @@ impl DbErrorNew for DbError {
b'd' => datatype = Some(field.value().to_owned()), b'd' => datatype = Some(field.value().to_owned()),
b'n' => constraint = Some(field.value().to_owned()), b'n' => constraint = Some(field.value().to_owned()),
b'F' => file = Some(field.value().to_owned()), b'F' => file = Some(field.value().to_owned()),
b'L' => line = Some(try!(field.value().parse::<u32>().map_err(|_| ::bad_response()))), b'L' => {
line = Some(try!(field.value().parse::<u32>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput,
"`L` field did not contain an integer")
})));
}
b'R' => routine = Some(field.value().to_owned()), b'R' => routine = Some(field.value().to_owned()),
b'V' => parsed_severity = Some(try!(Severity::from_str(field.value()).ok_or_else(::bad_response))), b'V' => {
parsed_severity = Some(try!(Severity::from_str(field.value()).ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput,
"`V` field contained an invalid value")
})));
}
_ => {}, _ => {},
} }
} }
Ok(DbError { Ok(DbError {
severity: try!(severity.ok_or_else(|| ::bad_response())), severity: try!(severity.ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "`S` field missing")
})),
parsed_severity: parsed_severity, parsed_severity: parsed_severity,
code: try!(code.ok_or_else(|| ::bad_response())), code: try!(code.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput,
message: try!(message.ok_or_else(|| ::bad_response())), "`C` field missing"))),
message: try!(message.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput,
"`M` field missing"))),
detail: detail, detail: detail,
hint: hint, hint: hint,
position: match normal_position { position: match normal_position {
@ -200,7 +223,10 @@ impl DbErrorNew for DbError {
Some(position) => { Some(position) => {
Some(ErrorPosition::Internal { Some(ErrorPosition::Internal {
position: position, position: position,
query: try!(internal_query.ok_or_else(|| ::bad_response())), query: try!(internal_query.ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput,
"`q` field missing but `p` field present")
})),
}) })
} }
None => None, None => None,
@ -220,14 +246,16 @@ impl DbErrorNew for DbError {
}) })
} }
fn new_connect<T>(fields: &mut ErrorFields) -> result::Result<T, ConnectError> { #[doc(hidden)]
pub fn new_connect<T>(fields: &mut ErrorFields) -> Result<T, ConnectError> {
match DbError::new_raw(fields) { match DbError::new_raw(fields) {
Ok(err) => Err(ConnectError::Db(Box::new(err))), Ok(err) => Err(ConnectError::Db(Box::new(err))),
Err(e) => Err(ConnectError::Io(e)), Err(e) => Err(ConnectError::Io(e)),
} }
} }
fn new<T>(fields: &mut ErrorFields) -> Result<T> { #[doc(hidden)]
pub fn new<T>(fields: &mut ErrorFields) -> Result<T, Error> {
match DbError::new_raw(fields) { match DbError::new_raw(fields) {
Ok(err) => Err(Error::Db(Box::new(err))), Ok(err) => Err(Error::Db(Box::new(err))),
Err(e) => Err(Error::Io(e)), Err(e) => Err(Error::Io(e)),

View File

@ -1,3 +1,9 @@
extern crate hex; #![allow(unknown_lints)] // for clippy
extern crate hex;
extern crate fallible_iterator;
extern crate phf;
extern crate postgres_protocol;
pub mod error;
pub mod params; pub mod params;

View File

@ -40,7 +40,6 @@ bufstream = "0.1"
fallible-iterator = "0.1.3" fallible-iterator = "0.1.3"
hex = "0.2" hex = "0.2"
log = "0.3" log = "0.3"
phf = "=0.7.20"
postgres-protocol = "0.2" postgres-protocol = "0.2"
bit-vec = { version = "0.4", optional = true } bit-vec = { version = "0.4", optional = true }
chrono = { version = "0.2.14", optional = true } chrono = { version = "0.2.14", optional = true }
@ -54,5 +53,7 @@ serde_json = { version = ">= 0.6, < 0.9", optional = true }
time = { version = "0.1.14", optional = true } time = { version = "0.1.14", optional = true }
uuid = { version = ">= 0.1, < 0.4", optional = true } uuid = { version = ">= 0.1, < 0.4", optional = true }
postgres-shared = { path = "../postgres-shared" }
[dev-dependencies] [dev-dependencies]
url = "1.0" url = "1.0"

View File

@ -76,8 +76,8 @@ extern crate hex;
#[cfg(not(feature = "no-logging"))] #[cfg(not(feature = "no-logging"))]
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate phf;
extern crate postgres_protocol; extern crate postgres_protocol;
extern crate postgres_shared;
use fallible_iterator::{FallibleIterator, FromFallibleIterator}; use fallible_iterator::{FallibleIterator, FromFallibleIterator};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -90,7 +90,7 @@ use std::result;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use postgres_protocol::authentication; use postgres_protocol::authentication;
use postgres_protocol::message::backend::{self, ErrorFields}; use postgres_protocol::message::backend;
use postgres_protocol::message::frontend; use postgres_protocol::message::frontend;
use error::{Error, ConnectError, SqlState, DbError}; use error::{Error, ConnectError, SqlState, DbError};
@ -103,13 +103,15 @@ use stmt::{Statement, Column};
use transaction::{Transaction, IsolationLevel}; use transaction::{Transaction, IsolationLevel};
use types::{IsNull, Kind, Type, SessionInfo, Oid, Other, WrongType, ToSql, FromSql, Field}; use types::{IsNull, Kind, Type, SessionInfo, Oid, Other, WrongType, ToSql, FromSql, Field};
#[doc(inline)]
pub use postgres_shared::error;
#[macro_use] #[macro_use]
mod macros; mod macros;
mod feature_check; mod feature_check;
mod priv_io; mod priv_io;
mod url; mod url;
pub mod error;
pub mod tls; pub mod tls;
pub mod notification; pub mod notification;
pub mod params; pub mod params;
@ -473,7 +475,7 @@ impl InnerConnection {
.map_err(Into::into) .map_err(Into::into)
.and_then(|oid| self.get_type(oid)) .and_then(|oid| self.get_type(oid))
.collect()); .collect());
let columns = match raw_columns { let columns = match raw_columns {
Some(body) => { Some(body) => {
try!(body.fields() try!(body.fields()
@ -1373,12 +1375,6 @@ trait OtherNew {
fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other; fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other;
} }
trait DbErrorNew {
fn new_raw(fields: &mut ErrorFields) -> io::Result<DbError>;
fn new_connect<T>(fields: &mut ErrorFields) -> result::Result<T, ConnectError>;
fn new<T>(fields: &mut ErrorFields) -> Result<T>;
}
trait RowsNew<'a> { trait RowsNew<'a> {
fn new(stmt: &'a Statement<'a>, data: Vec<RowData>) -> Rows<'a>; fn new(stmt: &'a Statement<'a>, data: Vec<RowData>) -> Rows<'a>;
fn new_owned(stmt: Statement<'a>, data: Vec<RowData>) -> Rows<'a>; fn new_owned(stmt: Statement<'a>, data: Vec<RowData>) -> Rows<'a>;

View File

@ -13,7 +13,7 @@ use types::{SessionInfo, Type, ToSql};
use rows::{Rows, LazyRows}; use rows::{Rows, LazyRows};
use transaction::Transaction; use transaction::Transaction;
use {bad_response, Connection, StatementInternals, Result, RowsNew, InnerConnection, RowData, use {bad_response, Connection, StatementInternals, Result, RowsNew, InnerConnection, RowData,
SessionInfoNew, LazyRowsNew, DbErrorNew, ColumnNew, StatementInfo, TransactionInternals}; SessionInfoNew, LazyRowsNew, ColumnNew, StatementInfo, TransactionInternals};
/// A prepared statement. /// A prepared statement.
pub struct Statement<'conn> { pub struct Statement<'conn> {