Overload Index for PostgresRow

RowIndex has to be implemented for int unfortunately since that's what a
literal ends up resolving to.
This commit is contained in:
Steven Fackler 2013-09-02 18:53:03 -07:00
parent 8ab3c1d04b
commit 3d8d35d840
2 changed files with 43 additions and 16 deletions

View File

@ -655,23 +655,37 @@ impl<'self> Container for PostgresRow<'self> {
}
}
impl<'self, T: FromSql> Index<uint, T> for PostgresRow<'self> {
fn index(&self, idx: &uint) -> T {
self.get(*idx)
}
}
impl<'self> PostgresRow<'self> {
pub fn get<T: FromSql>(&self, idx: uint) -> T {
impl<'self, I: RowIndex, T: FromSql> Index<I, T> for PostgresRow<'self> {
fn index(&self, idx: &I) -> T {
let idx = idx.idx(self.stmt);
FromSql::from_sql(self.stmt.result_desc[idx].type_oid,
&self.data[idx])
}
}
pub fn get_named<T: FromSql>(&self, col: &str) -> T {
let idx = match self.stmt.find_col_named(col) {
Some(idx) => idx,
None => fail!("No column with name %s", col)
};
self.get(idx)
pub trait RowIndex {
fn idx(&self, stmt: &PostgresStatement) -> uint;
}
impl RowIndex for uint {
fn idx(&self, _stmt: &PostgresStatement) -> uint {
*self
}
}
// This is a convenicence as the 0 in get[0] resolves to int :(
impl RowIndex for int {
fn idx(&self, _stmt: &PostgresStatement) -> uint {
assert!(*self >= 0);
*self as uint
}
}
impl<'self> RowIndex for &'self str {
fn idx(&self, stmt: &PostgresStatement) -> uint {
match stmt.find_col_named(*self) {
Some(idx) => idx,
None => fail!("No column with name %s", *self)
}
}
}

View File

@ -272,7 +272,7 @@ fn test_find_col_named() {
}
#[test]
fn test_find_get_named() {
fn test_get_named() {
do test_in_transaction |trans| {
trans.update("CREATE TABLE foo (
id SERIAL PRIMARY KEY,
@ -283,7 +283,20 @@ fn test_find_get_named() {
let result = stmt.query([]);
assert_eq!(~[10i32],
result.map(|row| { row.get_named("val") }).collect());
result.map(|row| { row["val"] }).collect());
}
}
#[test]
#[should_fail]
fn test_get_named_fail() {
do test_in_transaction |trans| {
trans.update("CREATE TABLE foo (id SERIAL PRIMARY KEY)", []);
trans.update("INSERT INTO foo DEFAULT VALUES", []);
let stmt = trans.prepare("SELECT id FROM foo");
let mut result = stmt.query([]);
let _: i32 = result.next().unwrap()["asdf"];
}
}