@@ -26,18 +26,19 @@ impl Drop for PostgresConnection {
26
26
}
27
27
}
28
28
29
- #[ deriving( ToStr ) ]
30
- pub struct PostgresError ;
31
-
32
29
#[ deriving( ToStr ) ]
33
30
pub enum PostgresConnectError {
34
31
InvalidUrl ,
35
32
MissingUser ,
36
- DbError ( PostgresError ) ,
33
+ DbError ( PostgresDbError ) ,
37
34
MissingPassword ,
38
35
UnsupportedAuthentication
39
36
}
40
37
38
+ #[ deriving( ToStr ) ]
39
+ // TODO this should have things in it
40
+ pub struct PostgresDbError ;
41
+
41
42
impl PostgresConnection {
42
43
pub fn connect ( url : & str ) -> PostgresConnection {
43
44
match PostgresConnection :: try_connect ( url) {
@@ -65,7 +66,9 @@ impl PostgresConnection {
65
66
} ;
66
67
let mut args = args;
67
68
68
- let socket_url = fmt!( "%s:%s" , host, port. unwrap_or_default( ~"5432 "));
69
+ // This seems silly
70
+ let socket_url = format!( "{:s}:{:s}" , host,
71
+ port. unwrap_or_default( ~"5432 "));
69
72
let addr: SocketAddr = match FromStr::from_str(socket_url) {
70
73
Some(addr) => addr,
71
74
None => return Err(InvalidUrl)
@@ -77,7 +80,7 @@ impl PostgresConnection {
77
80
next_stmt_id: Cell::new(0)
78
81
};
79
82
80
- // we have to clone here since we need the user again for auth
83
+ // We have to clone here since we need the user again for auth
81
84
args.push((~" user", user.user.clone()));
82
85
if !path.is_empty() {
83
86
args.push((~" database", path));
@@ -124,7 +127,7 @@ impl PostgresConnection {
124
127
};
125
128
self.write_message(&PasswordMessage(pass));
126
129
}
127
- AuthenticationMD5Password(nonce ) => {
130
+ AuthenticationMD5Password(salt ) => {
128
131
let UserInfo { user, pass } = user;
129
132
let pass = match pass {
130
133
Some(pass) => pass,
@@ -136,7 +139,7 @@ impl PostgresConnection {
136
139
let output = md5.result_str();
137
140
md5.reset();
138
141
md5.input_str(output);
139
- md5.input(nonce );
142
+ md5.input(salt );
140
143
let output = " md5" + md5.result_str();
141
144
self.write_message(&PasswordMessage(output.as_slice()));
142
145
}
@@ -145,12 +148,21 @@ impl PostgresConnection {
145
148
146
149
match self.read_message() {
147
150
AuthenticationOk => None,
148
- ErrorResponse(*) => Some(DbError(PostgresError )),
151
+ ErrorResponse(*) => Some(DbError(PostgresDbError )),
149
152
resp => fail!(" Bad response: %?", resp.to_str())
150
153
}
151
154
}
152
155
153
156
pub fn prepare<'a>(&'a self, query: &str) -> PostgresStatement<'a> {
157
+ match self.try_prepare(query) {
158
+ Ok(stmt) => stmt,
159
+ Err(err) => fail!(" Error preparing \"%s\" : %s", query,
160
+ err.to_str())
161
+ }
162
+ }
163
+
164
+ pub fn try_prepare<'a>(&'a self, query: &str)
165
+ -> Result<PostgresStatement<'a>, PostgresDbError> {
154
166
let id = self.next_stmt_id.take();
155
167
let stmt_name = format!(" statement_{ } ", id);
156
168
self.next_stmt_id.put_back(id + 1);
@@ -161,7 +173,7 @@ impl PostgresConnection {
161
173
162
174
match self.read_message() {
163
175
ParseComplete => (),
164
- resp @ ErrorResponse(*) => fail!(" Error : %? ", resp.to_str() ),
176
+ ErrorResponse(*) => return Err(PostgresDbError ),
165
177
resp => fail!(" Bad response: %?", resp.to_str())
166
178
}
167
179
@@ -182,12 +194,12 @@ impl PostgresConnection {
182
194
183
195
self.wait_for_ready();
184
196
185
- PostgresStatement {
197
+ Ok( PostgresStatement {
186
198
conn: self,
187
199
name: stmt_name,
188
200
num_params: num_params,
189
201
next_portal_id: Cell::new(0)
190
- }
202
+ })
191
203
}
192
204
193
205
pub fn in_transaction<T, E: ToStr>(&self, blk: &fn(&PostgresConnection)
@@ -257,7 +269,8 @@ impl<'self> PostgresStatement<'self> {
257
269
self.num_params
258
270
}
259
271
260
- fn execute(&self, portal_name: &str, params: &[&ToSql]) {
272
+ fn execute(&self, portal_name: &str, params: &[&ToSql])
273
+ -> Option<PostgresDbError> {
261
274
if self.num_params != params.len() {
262
275
fail!(" Expected %u params but got %u", self.num_params,
263
276
params.len());
@@ -274,15 +287,29 @@ impl<'self> PostgresStatement<'self> {
274
287
self.conn.write_message(&Sync);
275
288
276
289
match self.conn.read_message() {
277
- BindComplete => () ,
278
- resp @ ErrorResponse(*) => fail!(" Error : %? ", resp.to_str() ),
290
+ BindComplete => None ,
291
+ ErrorResponse(*) => Some(PostgresDbError ),
279
292
resp => fail!(" Bad response: %?", resp.to_str())
280
293
}
281
294
}
282
295
283
296
pub fn update(&self, params: &[&ToSql]) -> uint {
297
+ match self.try_update(params) {
298
+ Ok(count) => count,
299
+ Err(err) => fail!(" Error running update: %s", err.to_str())
300
+ }
301
+ }
302
+
303
+ pub fn try_update(&self, params: &[&ToSql])
304
+ -> Result<uint, PostgresDbError> {
284
305
// The unnamed portal is automatically cleaned up at sync time
285
- self.execute(" ", params);
306
+ match self.execute(" ", params) {
307
+ Some(err) => {
308
+ self.conn.wait_for_ready();
309
+ return Err(err);
310
+ }
311
+ None => ()
312
+ }
286
313
287
314
let mut num = 0;
288
315
loop {
@@ -298,21 +325,38 @@ impl<'self> PostgresStatement<'self> {
298
325
DataRow(*) => (),
299
326
EmptyQueryResponse => break,
300
327
NoticeResponse(*) => (),
301
- resp @ ErrorResponse(*) => fail!(" Error : %?", resp.to_str()),
328
+ ErrorResponse(*) => {
329
+ self.conn.wait_for_ready();
330
+ return Err(PostgresDbError);
331
+ }
302
332
resp => fail!(" Bad response: %?", resp.to_str())
303
333
}
304
334
}
305
335
self.conn.wait_for_ready();
306
336
307
- num
337
+ Ok( num)
308
338
}
309
339
310
340
pub fn query<'a>(&'a self, params: &[&ToSql]) -> PostgresResult<'a> {
341
+ match self.try_query(params) {
342
+ Ok(result) => result,
343
+ Err(err) => fail!(" Error running query: %s", err.to_str())
344
+ }
345
+ }
346
+
347
+ pub fn try_query<'a>(&'a self, params: &[&ToSql])
348
+ -> Result<PostgresResult<'a>, PostgresDbError> {
311
349
let id = self.next_portal_id.take();
312
350
let portal_name = format!(" { : s} _portal_{ } ", self.name.as_slice(), id);
313
351
self.next_portal_id.put_back(id + 1);
314
352
315
- self.execute(portal_name, params);
353
+ match self.execute(portal_name, params) {
354
+ Some(err) => {
355
+ self.conn.wait_for_ready();
356
+ return Err(err);
357
+ }
358
+ None => ()
359
+ }
316
360
317
361
let mut data = ~[];
318
362
loop {
@@ -321,16 +365,20 @@ impl<'self> PostgresStatement<'self> {
321
365
DataRow(row) => data.push(row),
322
366
CommandComplete(*) => break,
323
367
NoticeResponse(*) => (),
324
- resp @ ErrorResponse(*) => fail!(" Error : %?", resp.to_str()),
368
+ ErrorResponse(*) => {
369
+ self.conn.wait_for_ready();
370
+ return Err(PostgresDbError);
371
+ }
325
372
resp => fail!(" Bad response: %?" , resp. to_str( ) )
326
373
}
327
374
}
375
+ self . conn. wait_for_ready( ) ;
328
376
329
- PostgresResult {
377
+ Ok ( PostgresResult {
330
378
stmt: self ,
331
379
name: portal_name,
332
380
data: data
333
- }
381
+ } )
334
382
}
335
383
}
336
384
0 commit comments