Skip to content

Commit 736f530

Browse files
committed
Add Connection::query
Same deal as Connection::execute - a bit cheaper than preparing and executing the statement normally.
1 parent fcc2768 commit 736f530

4 files changed

Lines changed: 49 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,23 @@ impl Connection {
930930
stmt.execute(params)
931931
}
932932

933+
/// A convenience function for queries that are only run once.
934+
///
935+
/// If an error is returned, it could have come from either the preparation
936+
/// or execution of the statement.
937+
///
938+
/// On success, returns the resulting rows.
939+
///
940+
/// ## Panics
941+
///
942+
/// Panics if the number of parameters provided does not match the number
943+
/// expected.
944+
pub fn query<'a>(&'a self, query: &str, params: &[&ToSql]) -> Result<Rows<'a>> {
945+
let (param_types, columns) = try!(self.conn.borrow_mut().raw_prepare("", query));
946+
let stmt = Statement::new(self, "".to_owned(), param_types, columns, Cell::new(0), true);
947+
stmt.into_query(params)
948+
}
949+
933950
/// Begins a new transaction.
934951
///
935952
/// Returns a `Transaction` object which should be used instead of
@@ -1386,6 +1403,7 @@ trait DbErrorNew {
13861403

13871404
trait RowsNew<'a> {
13881405
fn new(stmt: &'a Statement<'a>, data: Vec<Vec<Option<Vec<u8>>>>) -> Rows<'a>;
1406+
fn new_owned(stmt: Statement<'a>, data: Vec<Vec<Option<Vec<u8>>>>) -> Rows<'a>;
13891407
}
13901408

13911409
trait LazyRowsNew<'trans, 'stmt> {
@@ -1413,6 +1431,8 @@ trait StatementInternals<'conn> {
14131431
-> Statement<'conn>;
14141432

14151433
fn conn(&self) -> &'conn Connection;
1434+
1435+
fn into_query(self, params: &[&ToSql]) -> Result<Rows<'conn>>;
14161436
}
14171437

14181438
trait ColumnNew {

src/rows.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ impl<'a> RowsNew<'a> for Rows<'a> {
4343
data: data,
4444
}
4545
}
46+
47+
fn new_owned(stmt: Statement<'a>, data: Vec<Vec<Option<Vec<u8>>>>) -> Rows<'a> {
48+
Rows {
49+
stmt: StatementContainer::Owned(stmt),
50+
data: data,
51+
}
52+
}
4653
}
4754

4855
impl<'a> fmt::Debug for Rows<'a> {

src/stmt.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ impl<'conn> StatementInternals<'conn> for Statement<'conn> {
6262
fn conn(&self) -> &'conn Connection {
6363
self.conn
6464
}
65+
66+
fn into_query(self, params: &[&ToSql]) -> Result<Rows<'conn>> {
67+
check_desync!(self.conn);
68+
self.inner_query("", 0, params).map(|(buf, _)| {
69+
Rows::new_owned(self, buf.into_iter().collect())
70+
})
71+
}
6572
}
6673

6774
impl<'conn> Statement<'conn> {

tests/test.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,3 +1001,18 @@ fn test_type_names() {
10011001
assert_eq!(Type::from_oid(id).unwrap().name(), name);
10021002
}
10031003
}
1004+
1005+
#[test]
1006+
fn test_conn_query() {
1007+
let conn = Connection::connect("postgres://postgres@localhost", &SslMode::None).unwrap();
1008+
conn.batch_execute("
1009+
CREATE TEMPORARY TABLE foo (id INT PRIMARY KEY);
1010+
INSERT INTO foo (id) VALUES (1), (2), (3);
1011+
").unwrap();
1012+
let ids = conn.query("SELECT id FROM foo ORDER BY id", &[])
1013+
.unwrap()
1014+
.iter()
1015+
.map(|r| r.get(0))
1016+
.collect::<Vec<i32>>();
1017+
assert_eq!(ids, [1, 2, 3]);
1018+
}

0 commit comments

Comments
 (0)