Move ugh_privacy stuff to normal places
Use private traits to expose constructors internally
This commit is contained in:
parent
0a4427e760
commit
81fc578ca6
182
src/error.rs
182
src/error.rs
@ -1,17 +1,193 @@
|
||||
pub use ugh_privacy::DbError;
|
||||
|
||||
use byteorder;
|
||||
use phf;
|
||||
use std::error;
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::result;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use Result;
|
||||
use {Result, DbErrorNew};
|
||||
use types::Type;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/sqlstate.rs"));
|
||||
|
||||
/// A Postgres error or notice.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct DbError {
|
||||
severity: String,
|
||||
code: SqlState,
|
||||
message: String,
|
||||
detail: Option<String>,
|
||||
hint: Option<String>,
|
||||
position: Option<ErrorPosition>,
|
||||
where_: Option<String>,
|
||||
schema: Option<String>,
|
||||
table: Option<String>,
|
||||
column: Option<String>,
|
||||
datatype: Option<String>,
|
||||
constraint: Option<String>,
|
||||
file: String,
|
||||
line: u32,
|
||||
routine: String,
|
||||
}
|
||||
|
||||
impl DbErrorNew for DbError {
|
||||
fn new_raw(fields: Vec<(u8, String)>) -> result::Result<DbError, ()> {
|
||||
let mut map: HashMap<_, _> = fields.into_iter().collect();
|
||||
Ok(DbError {
|
||||
severity: try!(map.remove(&b'S').ok_or(())),
|
||||
code: SqlState::from_code(try!(map.remove(&b'C').ok_or(()))),
|
||||
message: try!(map.remove(&b'M').ok_or(())),
|
||||
detail: map.remove(&b'D'),
|
||||
hint: map.remove(&b'H'),
|
||||
position: match map.remove(&b'P') {
|
||||
Some(pos) => Some(ErrorPosition::Normal(try!(pos.parse().map_err(|_| ())))),
|
||||
None => match map.remove(&b'p') {
|
||||
Some(pos) => Some(ErrorPosition::Internal {
|
||||
position: try!(pos.parse().map_err(|_| ())),
|
||||
query: try!(map.remove(&b'q').ok_or(()))
|
||||
}),
|
||||
None => None
|
||||
}
|
||||
},
|
||||
where_: map.remove(&b'W'),
|
||||
schema: map.remove(&b's'),
|
||||
table: map.remove(&b't'),
|
||||
column: map.remove(&b'c'),
|
||||
datatype: map.remove(&b'd'),
|
||||
constraint: map.remove(&b'n'),
|
||||
file: try!(map.remove(&b'F').ok_or(())),
|
||||
line: try!(map.remove(&b'L').and_then(|l| l.parse().ok()).ok_or(())),
|
||||
routine: try!(map.remove(&b'R').ok_or(())),
|
||||
})
|
||||
}
|
||||
|
||||
fn new_connect<T>(fields: Vec<(u8, String)>) -> result::Result<T, ConnectError> {
|
||||
match DbError::new_raw(fields) {
|
||||
Ok(err) => Err(ConnectError::DbError(err)),
|
||||
Err(()) => Err(ConnectError::BadResponse),
|
||||
}
|
||||
}
|
||||
|
||||
fn new<T>(fields: Vec<(u8, String)>) -> Result<T> {
|
||||
match DbError::new_raw(fields) {
|
||||
Ok(err) => Err(Error::DbError(err)),
|
||||
Err(()) => Err(Error::BadResponse),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DbError {
|
||||
/// The field contents are ERROR, FATAL, or PANIC (in an error message),
|
||||
/// or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a
|
||||
/// localized translation of one of these.
|
||||
pub fn severity(&self) -> &str {
|
||||
&self.severity
|
||||
}
|
||||
|
||||
/// The SQLSTATE code for the error.
|
||||
pub fn code(&self) -> &SqlState {
|
||||
&self.code
|
||||
}
|
||||
|
||||
/// The primary human-readable error message. This should be accurate but
|
||||
/// terse (typically one line).
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
|
||||
/// An optional secondary error message carrying more detail about the
|
||||
/// problem. Might run to multiple lines.
|
||||
pub fn detail(&self) -> Option<&str> {
|
||||
self.detail.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// An optional suggestion what to do about the problem. This is intended
|
||||
/// to differ from Detail in that it offers advice (potentially
|
||||
/// inappropriate) rather than hard facts. Might run to multiple lines.
|
||||
pub fn hint(&self) -> Option<&str> {
|
||||
self.hint.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// An optional error cursor position into either the original query string
|
||||
/// or an internally generated query.
|
||||
pub fn position(&self) -> Option<&ErrorPosition> {
|
||||
self.position.as_ref()
|
||||
}
|
||||
|
||||
/// An indication of the context in which the error occurred. Presently
|
||||
/// this includes a call stack traceback of active procedural language
|
||||
/// functions and internally-generated queries. The trace is one entry per
|
||||
/// line, most recent first.
|
||||
pub fn where_(&self) -> Option<&str> {
|
||||
self.where_.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific database object, the name
|
||||
/// of the schema containing that object, if any. (PostgreSQL 9.3+)
|
||||
pub fn schema(&self) -> Option<&str> {
|
||||
self.schema.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific table, the name of the
|
||||
/// table. (Refer to the schema name field for the name of the table's
|
||||
/// schema.) (PostgreSQL 9.3+)
|
||||
pub fn table(&self) -> Option<&str> {
|
||||
self.table.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific table column, the name of
|
||||
/// the column. (Refer to the schema and table name fields to identify the
|
||||
/// table.) (PostgreSQL 9.3+)
|
||||
pub fn column(&self) -> Option<&str> {
|
||||
self.column.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific data type, the name of the
|
||||
/// data type. (Refer to the schema name field for the name of the data
|
||||
/// type's schema.) (PostgreSQL 9.3+)
|
||||
pub fn datatype(&self) -> Option<&str> {
|
||||
self.datatype.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific constraint, the name of the
|
||||
/// constraint. Refer to fields listed above for the associated table or
|
||||
/// domain. (For this purpose, indexes are treated as constraints, even if
|
||||
/// they weren't created with constraint syntax.) (PostgreSQL 9.3+)
|
||||
pub fn constraint(&self) -> Option<&str> {
|
||||
self.constraint.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// The file name of the source-code location where the error was reported.
|
||||
pub fn file(&self) -> &str {
|
||||
&self.file
|
||||
}
|
||||
|
||||
/// The line number of the source-code location where the error was
|
||||
/// reported.
|
||||
pub fn line(&self) -> u32 {
|
||||
self.line
|
||||
}
|
||||
|
||||
/// The name of the source-code routine reporting the error.
|
||||
pub fn routine(&self) -> &str {
|
||||
&self.routine
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DbError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{}: {}", self.severity, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for DbError {
|
||||
fn description(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
}
|
||||
|
||||
/// Reasons a new Postgres connection could fail.
|
||||
#[derive(Debug)]
|
||||
pub enum ConnectError {
|
||||
|
45
src/lib.rs
45
src/lib.rs
@ -78,7 +78,7 @@ use std::path::PathBuf;
|
||||
|
||||
pub use error::{Error, ConnectError, SqlState, DbError, ErrorPosition};
|
||||
#[doc(inline)]
|
||||
pub use types::{Oid, Type, Kind, ToSql, FromSql, SessionInfo};
|
||||
pub use types::{Oid, Type, Other, Kind, ToSql, FromSql, SessionInfo};
|
||||
use io::{StreamWrapper, NegotiateSsl};
|
||||
use types::IsNull;
|
||||
#[doc(inline)]
|
||||
@ -95,7 +95,6 @@ mod macros;
|
||||
mod error;
|
||||
pub mod io;
|
||||
mod message;
|
||||
mod ugh_privacy;
|
||||
mod priv_io;
|
||||
mod url;
|
||||
mod util;
|
||||
@ -548,7 +547,7 @@ impl InnerConnection {
|
||||
conn.cancel_data.secret_key = secret_key;
|
||||
}
|
||||
ReadyForQuery { .. } => break,
|
||||
ErrorResponse { fields } => return ugh_privacy::dberror_new_connect(fields),
|
||||
ErrorResponse { fields } => return DbError::new_connect(fields),
|
||||
_ => return Err(ConnectError::BadResponse),
|
||||
}
|
||||
}
|
||||
@ -596,7 +595,7 @@ impl InnerConnection {
|
||||
debug_assert!(!self.desynchronized);
|
||||
match try_desync!(self, self.stream.read_message()) {
|
||||
NoticeResponse { fields } => {
|
||||
if let Ok(err) = ugh_privacy::dberror_new_raw(fields) {
|
||||
if let Ok(err) = DbError::new_raw(fields) {
|
||||
self.notice_handler.handle_notice(err);
|
||||
}
|
||||
Ok(None)
|
||||
@ -659,13 +658,13 @@ impl InnerConnection {
|
||||
| AuthenticationSCMCredential
|
||||
| AuthenticationGSS
|
||||
| AuthenticationSSPI => return Err(ConnectError::UnsupportedAuthentication),
|
||||
ErrorResponse { fields } => return ugh_privacy::dberror_new_connect(fields),
|
||||
ErrorResponse { fields } => return DbError::new_connect(fields),
|
||||
_ => return Err(ConnectError::BadResponse)
|
||||
}
|
||||
|
||||
match try!(self.read_message()) {
|
||||
AuthenticationOk => Ok(()),
|
||||
ErrorResponse { fields } => return ugh_privacy::dberror_new_connect(fields),
|
||||
ErrorResponse { fields } => return DbError::new_connect(fields),
|
||||
_ => return Err(ConnectError::BadResponse)
|
||||
}
|
||||
}
|
||||
@ -693,7 +692,7 @@ impl InnerConnection {
|
||||
ParseComplete => {}
|
||||
ErrorResponse { fields } => {
|
||||
try!(self.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => bad_response!(self),
|
||||
}
|
||||
@ -812,7 +811,7 @@ impl InnerConnection {
|
||||
Sync]));
|
||||
let resp = match try!(self.read_message()) {
|
||||
CloseComplete => Ok(()),
|
||||
ErrorResponse { fields } => ugh_privacy::dberror_new(fields),
|
||||
ErrorResponse { fields } => DbError::new(fields),
|
||||
_ => bad_response!(self)
|
||||
};
|
||||
try!(self.wait_for_ready());
|
||||
@ -851,7 +850,7 @@ impl InnerConnection {
|
||||
BindComplete => {}
|
||||
ErrorResponse { fields } => {
|
||||
try!(self.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => bad_response!(self)
|
||||
}
|
||||
@ -871,7 +870,7 @@ impl InnerConnection {
|
||||
}
|
||||
ErrorResponse { fields } => {
|
||||
try!(self.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => bad_response!(self)
|
||||
};
|
||||
@ -879,7 +878,7 @@ impl InnerConnection {
|
||||
CommandComplete { .. } => {}
|
||||
ErrorResponse { fields } => {
|
||||
try!(self.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => bad_response!(self)
|
||||
}
|
||||
@ -894,7 +893,7 @@ impl InnerConnection {
|
||||
}
|
||||
};
|
||||
|
||||
let type_ = Type::Other(Box::new(ugh_privacy::new_other(name, oid, kind)));
|
||||
let type_ = Type::Other(Box::new(Other::new(name, oid, kind)));
|
||||
self.unknown_types.insert(oid, type_.clone());
|
||||
Ok(type_)
|
||||
}
|
||||
@ -933,7 +932,7 @@ impl InnerConnection {
|
||||
}
|
||||
ErrorResponse { fields } => {
|
||||
try!(self.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -1466,7 +1465,7 @@ impl<'conn> Statement<'conn> {
|
||||
BindComplete => Ok(()),
|
||||
ErrorResponse { fields } => {
|
||||
try!(conn.wait_for_ready());
|
||||
ugh_privacy::dberror_new(fields)
|
||||
DbError::new(fields)
|
||||
}
|
||||
_ => {
|
||||
conn.desynchronized = true;
|
||||
@ -1527,7 +1526,7 @@ impl<'conn> Statement<'conn> {
|
||||
DataRow { .. } => {}
|
||||
ErrorResponse { fields } => {
|
||||
try!(conn.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
CommandComplete { tag } => {
|
||||
num = util::parse_update_count(tag);
|
||||
@ -1683,7 +1682,7 @@ fn read_rows(conn: &mut InnerConnection, buf: &mut VecDeque<Vec<Option<Vec<u8>>>
|
||||
DataRow { row } => buf.push_back(row),
|
||||
ErrorResponse { fields } => {
|
||||
try!(conn.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
CopyInResponse { .. } => {
|
||||
try!(conn.write_messages(&[
|
||||
@ -2133,7 +2132,7 @@ impl<'a> CopyInStatement<'a> {
|
||||
BindComplete => {},
|
||||
ErrorResponse { fields } => {
|
||||
try!(conn.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => {
|
||||
conn.desynchronized = true;
|
||||
@ -2210,7 +2209,7 @@ impl<'a> CopyInStatement<'a> {
|
||||
CommandComplete { tag } => util::parse_update_count(tag),
|
||||
ErrorResponse { fields } => {
|
||||
try!(conn.wait_for_ready());
|
||||
return ugh_privacy::dberror_new(fields);
|
||||
return DbError::new(fields);
|
||||
}
|
||||
_ => {
|
||||
conn.desynchronized = true;
|
||||
@ -2319,3 +2318,13 @@ impl<'a> GenericConnection for Transaction<'a> {
|
||||
self.is_active()
|
||||
}
|
||||
}
|
||||
|
||||
trait OtherNew {
|
||||
fn new(name: String, oid: Oid, kind: Kind) -> Other;
|
||||
}
|
||||
|
||||
trait DbErrorNew {
|
||||
fn new_raw(fields: Vec<(u8, String)>) -> result::Result<DbError, ()>;
|
||||
fn new_connect<T>(fields: Vec<(u8, String)>) -> result::Result<T, ConnectError>;
|
||||
fn new<T>(fields: Vec<(u8, String)>) -> Result<T>;
|
||||
}
|
||||
|
@ -6,12 +6,10 @@ use std::fmt;
|
||||
use std::io::prelude::*;
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
|
||||
|
||||
use {Result, SessionInfoNew, InnerConnection};
|
||||
use {Result, SessionInfoNew, InnerConnection, OtherNew};
|
||||
use error::Error;
|
||||
use util;
|
||||
|
||||
pub use ugh_privacy::Other;
|
||||
|
||||
/// Generates a simple implementation of `ToSql::accepts` which accepts the
|
||||
/// types passed to it.
|
||||
#[macro_export]
|
||||
@ -481,6 +479,41 @@ make_postgres_type! {
|
||||
3838 => EventTrigger: Kind::Simple
|
||||
}
|
||||
|
||||
/// Information about an unknown type.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Other {
|
||||
name: String,
|
||||
oid: Oid,
|
||||
kind: Kind,
|
||||
}
|
||||
|
||||
impl OtherNew for Other {
|
||||
fn new(name: String, oid: Oid, kind: Kind) -> Other {
|
||||
Other {
|
||||
name: name,
|
||||
oid: oid,
|
||||
kind: kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for types that can be created from a Postgres value.
|
||||
///
|
||||
/// # Types
|
||||
|
@ -1,215 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::result;
|
||||
|
||||
use Result;
|
||||
use types::{Oid, Kind};
|
||||
use error::{SqlState, ErrorPosition, ConnectError, Error};
|
||||
|
||||
/// Information about an unknown type.
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Other {
|
||||
name: String,
|
||||
oid: Oid,
|
||||
kind: Kind,
|
||||
}
|
||||
|
||||
pub fn new_other(name: String, oid: Oid, kind: Kind) -> Other {
|
||||
Other {
|
||||
name: name,
|
||||
oid: oid,
|
||||
kind: kind,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// A Postgres error or notice.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct DbError {
|
||||
severity: String,
|
||||
code: SqlState,
|
||||
message: String,
|
||||
detail: Option<String>,
|
||||
hint: Option<String>,
|
||||
position: Option<ErrorPosition>,
|
||||
where_: Option<String>,
|
||||
schema: Option<String>,
|
||||
table: Option<String>,
|
||||
column: Option<String>,
|
||||
datatype: Option<String>,
|
||||
constraint: Option<String>,
|
||||
file: String,
|
||||
line: u32,
|
||||
routine: String,
|
||||
}
|
||||
|
||||
pub fn dberror_new_raw(fields: Vec<(u8, String)>) -> result::Result<DbError, ()> {
|
||||
let mut map: HashMap<_, _> = fields.into_iter().collect();
|
||||
Ok(DbError {
|
||||
severity: try!(map.remove(&b'S').ok_or(())),
|
||||
code: SqlState::from_code(try!(map.remove(&b'C').ok_or(()))),
|
||||
message: try!(map.remove(&b'M').ok_or(())),
|
||||
detail: map.remove(&b'D'),
|
||||
hint: map.remove(&b'H'),
|
||||
position: match map.remove(&b'P') {
|
||||
Some(pos) => Some(ErrorPosition::Normal(try!(pos.parse().map_err(|_| ())))),
|
||||
None => match map.remove(&b'p') {
|
||||
Some(pos) => Some(ErrorPosition::Internal {
|
||||
position: try!(pos.parse().map_err(|_| ())),
|
||||
query: try!(map.remove(&b'q').ok_or(()))
|
||||
}),
|
||||
None => None
|
||||
}
|
||||
},
|
||||
where_: map.remove(&b'W'),
|
||||
schema: map.remove(&b's'),
|
||||
table: map.remove(&b't'),
|
||||
column: map.remove(&b'c'),
|
||||
datatype: map.remove(&b'd'),
|
||||
constraint: map.remove(&b'n'),
|
||||
file: try!(map.remove(&b'F').ok_or(())),
|
||||
line: try!(map.remove(&b'L').and_then(|l| l.parse().ok()).ok_or(())),
|
||||
routine: try!(map.remove(&b'R').ok_or(())),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dberror_new_connect<T>(fields: Vec<(u8, String)>) -> result::Result<T, ConnectError> {
|
||||
match dberror_new_raw(fields) {
|
||||
Ok(err) => Err(ConnectError::DbError(err)),
|
||||
Err(()) => Err(ConnectError::BadResponse),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dberror_new<T>(fields: Vec<(u8, String)>) -> Result<T> {
|
||||
match dberror_new_raw(fields) {
|
||||
Ok(err) => Err(Error::DbError(err)),
|
||||
Err(()) => Err(Error::BadResponse),
|
||||
}
|
||||
}
|
||||
|
||||
impl DbError {
|
||||
/// The field contents are ERROR, FATAL, or PANIC (in an error message),
|
||||
/// or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a
|
||||
/// localized translation of one of these.
|
||||
pub fn severity(&self) -> &str {
|
||||
&self.severity
|
||||
}
|
||||
|
||||
/// The SQLSTATE code for the error.
|
||||
pub fn code(&self) -> &SqlState {
|
||||
&self.code
|
||||
}
|
||||
|
||||
/// The primary human-readable error message. This should be accurate but
|
||||
/// terse (typically one line).
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
|
||||
/// An optional secondary error message carrying more detail about the
|
||||
/// problem. Might run to multiple lines.
|
||||
pub fn detail(&self) -> Option<&str> {
|
||||
self.detail.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// An optional suggestion what to do about the problem. This is intended
|
||||
/// to differ from Detail in that it offers advice (potentially
|
||||
/// inappropriate) rather than hard facts. Might run to multiple lines.
|
||||
pub fn hint(&self) -> Option<&str> {
|
||||
self.hint.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// An optional error cursor position into either the original query string
|
||||
/// or an internally generated query.
|
||||
pub fn position(&self) -> Option<&ErrorPosition> {
|
||||
self.position.as_ref()
|
||||
}
|
||||
|
||||
/// An indication of the context in which the error occurred. Presently
|
||||
/// this includes a call stack traceback of active procedural language
|
||||
/// functions and internally-generated queries. The trace is one entry per
|
||||
/// line, most recent first.
|
||||
pub fn where_(&self) -> Option<&str> {
|
||||
self.where_.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific database object, the name
|
||||
/// of the schema containing that object, if any. (PostgreSQL 9.3+)
|
||||
pub fn schema(&self) -> Option<&str> {
|
||||
self.schema.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific table, the name of the
|
||||
/// table. (Refer to the schema name field for the name of the table's
|
||||
/// schema.) (PostgreSQL 9.3+)
|
||||
pub fn table(&self) -> Option<&str> {
|
||||
self.table.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific table column, the name of
|
||||
/// the column. (Refer to the schema and table name fields to identify the
|
||||
/// table.) (PostgreSQL 9.3+)
|
||||
pub fn column(&self) -> Option<&str> {
|
||||
self.column.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific data type, the name of the
|
||||
/// data type. (Refer to the schema name field for the name of the data
|
||||
/// type's schema.) (PostgreSQL 9.3+)
|
||||
pub fn datatype(&self) -> Option<&str> {
|
||||
self.datatype.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// If the error was associated with a specific constraint, the name of the
|
||||
/// constraint. Refer to fields listed above for the associated table or
|
||||
/// domain. (For this purpose, indexes are treated as constraints, even if
|
||||
/// they weren't created with constraint syntax.) (PostgreSQL 9.3+)
|
||||
pub fn constraint(&self) -> Option<&str> {
|
||||
self.constraint.as_ref().map(|s| &**s)
|
||||
}
|
||||
|
||||
/// The file name of the source-code location where the error was reported.
|
||||
pub fn file(&self) -> &str {
|
||||
&self.file
|
||||
}
|
||||
|
||||
/// The line number of the source-code location where the error was
|
||||
/// reported.
|
||||
pub fn line(&self) -> u32 {
|
||||
self.line
|
||||
}
|
||||
|
||||
/// The name of the source-code routine reporting the error.
|
||||
pub fn routine(&self) -> &str {
|
||||
&self.routine
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DbError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{}: {}", self.severity, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for DbError {
|
||||
fn description(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user