forked from sfackler/rust-postgres
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrows.rs
84 lines (73 loc) · 2.25 KB
/
rows.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! Postgres rows.
use postgres_shared::rows::RowData;
use postgres_shared::stmt::Column;
use std::error::Error;
use std::fmt;
use std::sync::Arc;
#[doc(inline)]
pub use postgres_shared::rows::RowIndex;
use types::{WrongType, FromSql};
/// A row from Postgres.
pub struct Row {
columns: Arc<Vec<Column>>,
data: RowData,
}
impl Row {
pub(crate) fn new(columns: Arc<Vec<Column>>, data: RowData) -> Row {
Row {
columns: columns,
data: data,
}
}
/// Returns information about the columns in the row.
pub fn columns(&self) -> &[Column] {
&self.columns
}
/// Returns the number of values in the row
pub fn len(&self) -> usize {
self.columns.len()
}
/// Retrieves the contents of a field of the row.
///
/// A field can be accessed by the name or index of its column, though
/// access by index is more efficient. Rows are 0-indexed.
///
/// # Panics
///
/// Panics if the index does not reference a column or the return type is
/// not compatible with the Postgres type.
pub fn get<T, I>(&self, idx: I) -> T
where
T: FromSql,
I: RowIndex + fmt::Debug,
{
match self.try_get(&idx) {
Ok(Some(v)) => v,
Ok(None) => panic!("no such column {:?}", idx),
Err(e) => panic!("error retrieving row {:?}: {}", idx, e),
}
}
/// Retrieves the contents of a field of the row.
///
/// A field can be accessed by the name or index of its column, though
/// access by index is more efficient. Rows are 0-indexed.
///
/// Returns `None` if the index does not reference a column, `Some(Err(..))`
/// if there was an error converting the result value, and `Some(Ok(..))`
/// on success.
pub fn try_get<T, I>(&self, idx: I) -> Result<Option<T>, Box<Error + Sync + Send>>
where
T: FromSql,
I: RowIndex,
{
let idx = match idx.__idx(&self.columns) {
Some(idx) => idx,
None => return Ok(None),
};
let ty = self.columns[idx].type_();
if !T::accepts(ty) {
return Err(Box::new(WrongType::new(ty.clone())));
}
T::from_sql_nullable(ty, self.data.get(idx)).map(Some)
}
}