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
//! Nonblocking mode row fetch
use std::sync::atomic::Ordering;
use crate::{Result, Error, Rows, Row, oci::*};
impl<'a> Rows<'a> {
/**
Returns the next row in the SELECT's result set.
# Example
```
# sibyl::block_on(async {
# let oracle = sibyl::env()?;
# let dbname = std::env::var("DBNAME").expect("database name");
# let dbuser = std::env::var("DBUSER").expect("user name");
# let dbpass = std::env::var("DBPASS").expect("password");
# let session = oracle.connect(&dbname, &dbuser, &dbpass).await?;
let stmt = session.prepare("
SELECT street_address, postal_code, city, state_province
FROM hr.locations
WHERE country_id = :id
ORDER BY location_id
").await?;
let rows = stmt.query("CA").await?;
let mut res = Vec::new();
while let Some( row ) = rows.next().await? {
// &str does not live long enough to be useful for
// the `street_address`
let street_address : Option<String> = row.get(0)?;
let postal_code : Option<&str> = row.get(1)?;
let city : Option<&str> = row.get(2)?;
let state_province : Option<&str> = row.get(3)?;
let city_address = format!("{} {} {}",
city .unwrap_or_default(),
state_province .unwrap_or_default(),
postal_code .unwrap_or_default(),
);
res.push((street_address.unwrap_or_default(), city_address));
}
assert_eq!(res.len(), 2);
assert_eq!(res[0].1, "Toronto Ontario M5V 2L7");
assert_eq!(res[1].1, "Whitehorse Yukon YSW 9T2");
# Ok::<(),sibyl::Error>(()) }).expect("Ok from async");
```
*/
pub async fn next(&'a self) -> Result<Option<Row<'a>>> {
if self.last_result.load(Ordering::Acquire) == OCI_NO_DATA {
Ok( None )
} else {
let stmt: &OCIStmt = self.rset.as_ref();
let err: &OCIError = self.rset.as_ref();
let res = futures::StmtFetch::new(self.rset.session().get_svc(), stmt, err).await?;
self.last_result.store(res, Ordering::Release);
match res {
OCI_NO_DATA => Ok( None ),
OCI_SUCCESS | OCI_SUCCESS_WITH_INFO => Ok( Some(Row::new(self)) ),
_ => Err( Error::oci(self.rset.as_ref(), res) )
}
}
}
}
