Skip to content

Commit 557a159

Browse files
committed
Add a trait abstracting over transactions and connections
This is implemented *in addition* to the intrinsic methods because having to import a trait to call `prepare` sucks. Closes rust-postgres#63
1 parent b581e3a commit 557a159

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,3 +1718,62 @@ impl<'a> PostgresCopyInStatement<'a> {
17181718
self.finish_inner()
17191719
}
17201720
}
1721+
1722+
/// A trait allowing abstraction over connections and transactions
1723+
pub trait GenericConnection {
1724+
/// Like `PostgresConnection::prepare`.
1725+
fn prepare<'a>(&'a self, query: &str) -> PostgresResult<PostgresStatement<'a>>;
1726+
1727+
/// Like `PostgresConnection::execute`.
1728+
fn execute(&self, query: &str, params: &[&ToSql]) -> PostgresResult<uint> {
1729+
self.prepare(query).and_then(|s| s.execute(params))
1730+
}
1731+
1732+
/// Like `PostgresConnection::prepare_copy_in`.
1733+
fn prepare_copy_in<'a>(&'a self, table: &str, columns: &[&str])
1734+
-> PostgresResult<PostgresCopyInStatement<'a>>;
1735+
1736+
/// Like `PostgresConnection::transaction`.
1737+
fn transaction<'a>(&'a self) -> PostgresResult<PostgresTransaction<'a>>;
1738+
1739+
/// Like `PostgresConnection::batch_execute`.
1740+
fn batch_execute(&self, query: &str) -> PostgresResult<()>;
1741+
}
1742+
1743+
impl GenericConnection for PostgresConnection {
1744+
fn prepare<'a>(&'a self, query: &str) -> PostgresResult<PostgresStatement<'a>> {
1745+
self.prepare(query)
1746+
}
1747+
1748+
fn transaction<'a>(&'a self) -> PostgresResult<PostgresTransaction<'a>> {
1749+
self.transaction()
1750+
}
1751+
1752+
fn prepare_copy_in<'a>(&'a self, table: &str, columns: &[&str])
1753+
-> PostgresResult<PostgresCopyInStatement<'a>> {
1754+
self.prepare_copy_in(table, columns)
1755+
}
1756+
1757+
fn batch_execute(&self, query: &str) -> PostgresResult<()> {
1758+
self.batch_execute(query)
1759+
}
1760+
}
1761+
1762+
impl<'a> GenericConnection for PostgresTransaction<'a> {
1763+
fn prepare<'a>(&'a self, query: &str) -> PostgresResult<PostgresStatement<'a>> {
1764+
self.prepare(query)
1765+
}
1766+
1767+
fn transaction<'a>(&'a self) -> PostgresResult<PostgresTransaction<'a>> {
1768+
self.transaction()
1769+
}
1770+
1771+
fn prepare_copy_in<'a>(&'a self, table: &str, columns: &[&str])
1772+
-> PostgresResult<PostgresCopyInStatement<'a>> {
1773+
self.prepare_copy_in(table, columns)
1774+
}
1775+
1776+
fn batch_execute(&self, query: &str) -> PostgresResult<()> {
1777+
self.batch_execute(query)
1778+
}
1779+
}

tests/test.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::time::Duration;
1414
use postgres::{PostgresNoticeHandler,
1515
PostgresNotification,
1616
PostgresConnection,
17+
GenericConnection,
1718
ResultDescription,
1819
RequireSsl,
1920
PreferSsl,
@@ -761,3 +762,16 @@ fn test_batch_execute_copy_from_err() {
761762
_ => fail!("Expected error"),
762763
}
763764
}
765+
766+
#[test]
767+
// Just make sure the impls don't infinite loop
768+
fn test_generic_connection() {
769+
fn f<T>(t: &T) where T: GenericConnection {
770+
or_fail!(t.execute("SELECT 1", []));
771+
}
772+
773+
let conn = or_fail!(PostgresConnection::connect("postgres://postgres@localhost", &NoSsl));
774+
f(&conn);
775+
let trans = or_fail!(conn.transaction());
776+
f(&trans);
777+
}

0 commit comments

Comments
 (0)