@@ -74,17 +74,25 @@ use extra::container::Deque;
7474use extra:: ringbuf:: RingBuf ;
7575use extra:: url:: { UserInfo , Url } ;
7676use ssl:: { SslStream , SslContext } ;
77- use ssl:: error:: SslError ;
7877use std:: cell:: Cell ;
79- use std:: hashmap:: HashMap ;
8078use std:: rt:: io:: { Writer , io_error, Decorator } ;
8179use std:: rt:: io:: buffered:: BufferedStream ;
8280use std:: rt:: io:: net;
8381use std:: rt:: io:: net:: ip:: { Port , SocketAddr } ;
8482use std:: rt:: io:: net:: tcp:: TcpStream ;
8583use std:: task;
8684
87- use self :: error:: hack:: PostgresSqlState ;
85+ use self :: error:: { PostgresConnectError ,
86+ PostgresDbError ,
87+ InvalidUrl ,
88+ DnsError ,
89+ SocketError ,
90+ NoSslSupport ,
91+ SslError ,
92+ MissingUser ,
93+ DbError ,
94+ UnsupportedAuthentication ,
95+ MissingPassword } ;
8896use self :: message:: { BackendMessage ,
8997 AuthenticationOk ,
9098 AuthenticationKerberosV5 ,
@@ -181,147 +189,6 @@ impl<'self> Iterator<PostgresNotification> for
181189 }
182190}
183191
184- /// Reasons a new Postgres connection could fail
185- #[ deriving( ToStr ) ]
186- pub enum PostgresConnectError {
187- /// The provided URL could not be parsed
188- InvalidUrl ,
189- /// The URL was missing a user
190- MissingUser ,
191- /// DNS lookup failed
192- DnsError ,
193- /// There was an error opening a socket to the server
194- SocketError ,
195- /// An error from the Postgres server itself
196- DbError ( PostgresDbError ) ,
197- /// A password was required but not provided in the URL
198- MissingPassword ,
199- /// The Postgres server requested an authentication method not supported
200- /// by the driver
201- UnsupportedAuthentication ,
202- /// The Postgres server does not support SSL encryption
203- NoSslSupport ,
204- /// There was an error initializing the SSL session
205- SslError ( SslError )
206- }
207-
208- /// Represents the position of an error in a query
209- #[ deriving( ToStr ) ]
210- pub enum PostgresErrorPosition {
211- /// A position in the original query
212- Position ( uint ) ,
213- /// A position in an internally generated query
214- InternalPosition {
215- /// The byte position
216- position : uint ,
217- /// A query generated by the Postgres server
218- query : ~str
219- }
220- }
221-
222- /// Encapsulates a Postgres error or notice.
223- #[ deriving( ToStr ) ]
224- pub struct PostgresDbError {
225- /// The field contents are ERROR, FATAL, or PANIC (in an error message),
226- /// or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a
227- /// localized translation of one of these.
228- severity : ~str ,
229- /// The SQLSTATE code for the error.
230- code : PostgresSqlState ,
231- /// The primary human-readable error message. This should be accurate but
232- /// terse (typically one line).
233- message : ~str ,
234- /// An optional secondary error message carrying more detail about the
235- /// problem. Might run to multiple lines.
236- detail : Option < ~str > ,
237- /// An optional suggestion what to do about the problem. This is intended
238- /// to differ from Detail in that it offers advice (potentially
239- /// inappropriate) rather than hard facts. Might run to multiple lines.
240- hint : Option < ~str > ,
241- /// An optional error cursor position into either the original query string
242- /// or an internally generated query.
243- position : Option < PostgresErrorPosition > ,
244- /// An indication of the context in which the error occurred. Presently
245- /// this includes a call stack traceback of active procedural language
246- /// functions and internally-generated queries. The trace is one entry per
247- /// line, most recent first.
248- where : Option < ~str > ,
249- /// If the error was associated with a specific database object, the name
250- /// of the schema containing that object, if any. (PostgreSQL 9.3+)
251- schema : Option < ~str > ,
252- /// If the error was associated with a specific table, the name of the
253- /// table. (Refer to the schema name field for the name of the table's
254- /// schema.) (PostgreSQL 9.3+)
255- table : Option < ~str > ,
256- /// If the error was associated with a specific table column, the name of
257- /// the column. (Refer to the schema and table name fields to identify the
258- /// table.) (PostgreSQL 9.3+)
259- column : Option < ~str > ,
260- /// If the error was associated with a specific data type, the name of the
261- /// data type. (Refer to the schema name field for the name of the data
262- /// type's schema.) (PostgreSQL 9.3+)
263- datatype : Option < ~str > ,
264- /// If the error was associated with a specific constraint, the name of the
265- /// constraint. Refer to fields listed above for the associated table or
266- /// domain. (For this purpose, indexes are treated as constraints, even if
267- /// they weren't created with constraint syntax.) (PostgreSQL 9.3+)
268- constraint : Option < ~str > ,
269- /// The file name of the source-code location where the error was reported.
270- file : ~str ,
271- /// The line number of the source-code location where the error was
272- /// reported.
273- line : uint ,
274- /// The name of the source-code routine reporting the error.
275- routine : ~str
276- }
277-
278- impl PostgresDbError {
279- fn new ( fields : ~[ ( u8 , ~str ) ] ) -> PostgresDbError {
280- // move_rev_iter is more efficient than move_iter
281- let mut map: HashMap < u8 , ~str > = fields. move_rev_iter ( ) . collect ( ) ;
282- PostgresDbError {
283- severity : map. pop ( & ( 'S' as u8 ) ) . unwrap ( ) ,
284- code : FromStr :: from_str ( map. pop ( & ( 'C' as u8 ) ) . unwrap ( ) ) . unwrap ( ) ,
285- message : map. pop ( & ( 'M' as u8 ) ) . unwrap ( ) ,
286- detail : map. pop ( & ( 'D' as u8 ) ) ,
287- hint : map. pop ( & ( 'H' as u8 ) ) ,
288- position : match map. pop ( & ( 'P' as u8 ) ) {
289- Some ( pos) => Some ( Position ( FromStr :: from_str ( pos) . unwrap ( ) ) ) ,
290- None => match map. pop ( & ( 'p' as u8 ) ) {
291- Some ( pos) => Some ( InternalPosition {
292- position : FromStr :: from_str ( pos) . unwrap ( ) ,
293- query : map. pop ( & ( 'q' as u8 ) ) . unwrap ( )
294- } ) ,
295- None => None
296- }
297- } ,
298- where : map. pop ( & ( 'W' as u8 ) ) ,
299- schema : map. pop ( & ( 's' as u8 ) ) ,
300- table : map. pop ( & ( 't' as u8 ) ) ,
301- column : map. pop ( & ( 'c' as u8 ) ) ,
302- datatype : map. pop ( & ( 'd' as u8 ) ) ,
303- constraint : map. pop ( & ( 'n' as u8 ) ) ,
304- file : map. pop ( & ( 'F' as u8 ) ) . unwrap ( ) ,
305- line : FromStr :: from_str ( map. pop ( & ( 'L' as u8 ) ) . unwrap ( ) ) . unwrap ( ) ,
306- routine : map. pop ( & ( 'R' as u8 ) ) . unwrap ( )
307- }
308- }
309-
310- fn pretty_error ( & self , query : & str ) -> ~str {
311- match self . position {
312- Some ( Position ( pos) ) =>
313- format ! ( "{}: {} at position {} in\n {}" , self . severity,
314- self . message, pos, query) ,
315- Some ( InternalPosition { position, query : ref inner_query } ) =>
316- format ! ( "{}: {} at position {} in\n {} called from\n {}" ,
317- self . severity, self . message, position, * inner_query,
318- query) ,
319- None => format ! ( "{}: {} in\n {}" , self . severity, self . message,
320- query)
321- }
322- }
323- }
324-
325192/// Contains information necessary to cancel queries for a session
326193pub struct PostgresCancelData {
327194 /// The process ID of the session
0 commit comments