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;
fn main() {
let path = Path::new("../src");
let path = Path::new("..");
sqlstate::build(path);
type_gen::build(path);
}

View File

@ -13,7 +13,7 @@ struct Code {
}
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();

View File

@ -20,7 +20,7 @@ struct Type {
}
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 types = parse_types(&ranges);

View File

@ -5,3 +5,6 @@ authors = ["Steven Fackler <sfackler@gmail.com>"]
[dependencies]
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::fmt;
use std::io;
use std::result;
pub use self::sqlstate::SqlState;
use {Result, DbErrorNew};
mod sqlstate;
@ -141,8 +139,9 @@ pub struct DbError {
_p: (),
}
impl DbErrorNew for DbError {
fn new_raw(fields: &mut ErrorFields) -> io::Result<DbError> {
impl DbError {
#[doc(hidden)]
pub fn new_raw(fields: &mut ErrorFields) -> io::Result<DbError> {
let mut severity = None;
let mut parsed_severity = None;
let mut code = None;
@ -169,8 +168,18 @@ impl DbErrorNew for DbError {
b'M' => message = Some(field.value().to_owned()),
b'D' => detail = 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' => internal_position = Some(try!(field.value().parse::<u32>().map_err(|_| ::bad_response()))),
b'P' => {
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'W' => where_ = 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'n' => constraint = 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'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 {
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,
code: try!(code.ok_or_else(|| ::bad_response())),
message: try!(message.ok_or_else(|| ::bad_response())),
code: try!(code.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput,
"`C` field missing"))),
message: try!(message.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput,
"`M` field missing"))),
detail: detail,
hint: hint,
position: match normal_position {
@ -200,7 +223,10 @@ impl DbErrorNew for DbError {
Some(position) => {
Some(ErrorPosition::Internal {
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,
@ -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) {
Ok(err) => Err(ConnectError::Db(Box::new(err))),
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) {
Ok(err) => Err(Error::Db(Box::new(err))),
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;

View File

@ -40,7 +40,6 @@ bufstream = "0.1"
fallible-iterator = "0.1.3"
hex = "0.2"
log = "0.3"
phf = "=0.7.20"
postgres-protocol = "0.2"
bit-vec = { version = "0.4", 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 }
uuid = { version = ">= 0.1, < 0.4", optional = true }
postgres-shared = { path = "../postgres-shared" }
[dev-dependencies]
url = "1.0"

View File

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