@@ -257,7 +257,7 @@ impl PostgresConnection {
257257 })
258258 }
259259
260- pub fn prepare<'a>(&'a self, query: &str) -> PostgresStatement <'a> {
260+ pub fn prepare<'a>(&'a self, query: &str) -> NormalPostgresStatement <'a> {
261261 match self.try_prepare(query) {
262262 Ok(stmt) => stmt,
263263 Err(err) => fail2!(" Error preparing \"{ } \" : { } ", query,
@@ -266,7 +266,7 @@ impl PostgresConnection {
266266 }
267267
268268 pub fn try_prepare<'a>(&'a self, query: &str)
269- -> Result<PostgresStatement <'a>, PostgresDbError> {
269+ -> Result<NormalPostgresStatement <'a>, PostgresDbError> {
270270 let id = self.next_stmt_id.take();
271271 let stmt_name = format!(" statement_{ } ", id);
272272 self.next_stmt_id.put_back(id + 1);
@@ -303,7 +303,7 @@ impl PostgresConnection {
303303
304304 self.wait_for_ready();
305305
306- Ok(PostgresStatement {
306+ Ok(NormalPostgresStatement {
307307 conn: self,
308308 name: stmt_name,
309309 param_types: param_types,
@@ -370,13 +370,16 @@ pub struct PostgresTransaction<'self> {
370370}
371371
372372impl<'self> PostgresTransaction<'self> {
373- pub fn prepare<'a>(&'a self, query: &str) -> PostgresStatement<'a> {
374- self.conn.prepare(query)
373+ pub fn prepare<'a>(&'a self, query: &str)
374+ -> TransactionalPostgresStatement<'a> {
375+ TransactionalPostgresStatement { stmt: self.conn.prepare(query) }
375376 }
376377
377378 pub fn try_prepare<'a>(&'a self, query: &str)
378- -> Result<PostgresStatement<'a>, PostgresDbError> {
379- self.conn.try_prepare(query)
379+ -> Result<TransactionalPostgresStatement<'a>, PostgresDbError> {
380+ do self.conn.try_prepare(query).map_move |stmt| {
381+ TransactionalPostgresStatement { stmt: stmt }
382+ }
380383 }
381384
382385 pub fn update(&self, query: &str, params: &[&ToSql]) -> uint {
@@ -405,15 +408,25 @@ impl<'self> PostgresTransaction<'self> {
405408 }
406409}
407410
408- pub struct PostgresStatement<'self> {
411+ pub trait PostgresStatement {
412+ fn num_params(&self) -> uint;
413+ fn update(&self, params: &[&ToSql]) -> uint;
414+ fn try_update(&self, params: &[&ToSql]) -> Result<uint, PostgresDbError>;
415+ fn query<'a>(&'a self, params: &[&ToSql]) -> PostgresResult<'a>;
416+ fn try_query<'a>(&'a self, params: &[&ToSql])
417+ -> Result<PostgresResult<'a>, PostgresDbError>;
418+ fn find_col_named(&self, col: &str) -> Option<uint>;
419+ }
420+
421+ pub struct NormalPostgresStatement<'self> {
409422 priv conn: &'self PostgresConnection,
410423 priv name: ~str,
411424 priv param_types: ~[Oid],
412425 priv result_desc: ~[RowDescriptionEntry],
413426}
414427
415428#[unsafe_destructor]
416- impl<'self> Drop for PostgresStatement <'self> {
429+ impl<'self> Drop for NormalPostgresStatement <'self> {
417430 fn drop(&self) {
418431 do io_error::cond.trap(|_| {}).inside {
419432 self.conn.write_messages([
@@ -432,11 +445,7 @@ impl<'self> Drop for PostgresStatement<'self> {
432445 }
433446}
434447
435- impl<'self> PostgresStatement<'self> {
436- pub fn num_params(&self) -> uint {
437- self.param_types.len()
438- }
439-
448+ impl<'self> NormalPostgresStatement<'self> {
440449 fn execute(&self, portal_name: &str, params: &[&ToSql])
441450 -> Option<PostgresDbError> {
442451 let mut formats = ~[];
@@ -473,15 +482,21 @@ impl<'self> PostgresStatement<'self> {
473482 }
474483 })
475484 }
485+ }
476486
477- pub fn update(&self, params: &[&ToSql]) -> uint {
487+ impl<'self> PostgresStatement for NormalPostgresStatement<'self> {
488+ fn num_params(&self) -> uint {
489+ self.param_types.len()
490+ }
491+
492+ fn update(&self, params: &[&ToSql]) -> uint {
478493 match self.try_update(params) {
479494 Ok(count) => count,
480495 Err(err) => fail2!(" Error running update: { } ", err.to_str())
481496 }
482497 }
483498
484- pub fn try_update(&self, params: &[&ToSql])
499+ fn try_update(&self, params: &[&ToSql])
485500 -> Result<uint, PostgresDbError> {
486501 match self.execute(" ", params) {
487502 Some(err) => {
@@ -518,16 +533,16 @@ impl<'self> PostgresStatement<'self> {
518533 Ok(num)
519534 }
520535
521- pub fn query(&'self self, params: &[&ToSql])
522- -> PostgresResult<'self > {
536+ fn query<'a> (&'a self, params: &[&ToSql])
537+ -> PostgresResult<'a > {
523538 match self.try_query(params) {
524539 Ok(result) => result,
525540 Err(err) => fail2!(" Error running query: { } ", err.to_str())
526541 }
527542 }
528543
529- pub fn try_query(&'self self, params: &[&ToSql])
530- -> Result<PostgresResult<'self >, PostgresDbError> {
544+ fn try_query<'a> (&'a self, params: &[&ToSql])
545+ -> Result<PostgresResult<'a >, PostgresDbError> {
531546 match self.execute(" ", params) {
532547 Some(err) => {
533548 return Err(err);
@@ -555,15 +570,46 @@ impl<'self> PostgresStatement<'self> {
555570 })
556571 }
557572
558- pub fn find_col_named(&self, col: &str) -> Option<uint> {
573+ fn find_col_named(&self, col: &str) -> Option<uint> {
559574 do self.result_desc.iter().position |desc| {
560575 desc.name.as_slice() == col
561576 }
562577 }
563578}
564579
580+ pub struct TransactionalPostgresStatement<'self> {
581+ priv stmt: NormalPostgresStatement<'self>
582+ }
583+
584+ impl<'self> PostgresStatement for TransactionalPostgresStatement<'self> {
585+ fn num_params(&self) -> uint {
586+ self.stmt.num_params()
587+ }
588+
589+ fn update(&self, params: &[&ToSql]) -> uint {
590+ self.stmt.update(params)
591+ }
592+
593+ fn try_update(&self, params: &[&ToSql]) -> Result<uint, PostgresDbError> {
594+ self.stmt.try_update(params)
595+ }
596+
597+ fn query<'a>(&'a self, params: &[&ToSql]) -> PostgresResult<'a> {
598+ self.stmt.query(params)
599+ }
600+
601+ fn try_query<'a>(&'a self, params: &[&ToSql])
602+ -> Result<PostgresResult<'a>, PostgresDbError> {
603+ self.stmt.try_query(params)
604+ }
605+
606+ fn find_col_named(&self, col: &str) -> Option<uint> {
607+ self.stmt.find_col_named(col)
608+ }
609+ }
610+
565611pub struct PostgresResult<'self> {
566- priv stmt: &'self PostgresStatement <'self>,
612+ priv stmt: &'self NormalPostgresStatement <'self>,
567613 priv data: ~[~[Option<~[u8]>]]
568614}
569615
@@ -579,7 +625,7 @@ impl<'self> Iterator<PostgresRow<'self>> for PostgresResult<'self> {
579625}
580626
581627pub struct PostgresRow<'self> {
582- priv stmt: &'self PostgresStatement <'self>,
628+ priv stmt: &'self NormalPostgresStatement <'self>,
583629 priv data: ~[Option<~[u8]>]
584630}
585631
@@ -598,25 +644,25 @@ impl<'self, I: RowIndex, T: FromSql> Index<I, T> for PostgresRow<'self> {
598644}
599645
600646pub trait RowIndex {
601- fn idx(&self, stmt: &PostgresStatement ) -> uint;
647+ fn idx(&self, stmt: &NormalPostgresStatement ) -> uint;
602648}
603649
604650impl RowIndex for uint {
605- fn idx(&self, _stmt: &PostgresStatement ) -> uint {
651+ fn idx(&self, _stmt: &NormalPostgresStatement ) -> uint {
606652 *self
607653 }
608654}
609655
610656// This is a convenicence as the 0 in get[0] resolves to int :(
611657impl RowIndex for int {
612- fn idx(&self, _stmt: &PostgresStatement ) -> uint {
658+ fn idx(&self, _stmt: &NormalPostgresStatement ) -> uint {
613659 assert!(*self >= 0);
614660 *self as uint
615661 }
616662}
617663
618664impl<'self> RowIndex for &'self str {
619- fn idx(&self, stmt: &PostgresStatement ) -> uint {
665+ fn idx(&self, stmt: &NormalPostgresStatement ) -> uint {
620666 match stmt.find_col_named(*self) {
621667 Some(idx) => idx,
622668 None => fail2!(" No column with name { } " , * self )
0 commit comments