use crate::errors::ExecResult;
use crate::value::Row;
pub trait RowSource {
fn next_row(&mut self) -> ExecResult<Option<Row>>;
}
pub fn drain<S: RowSource + ?Sized>(source: &mut S) -> ExecResult<Vec<Row>> {
let mut out = Vec::new();
while let Some(row) = source.next_row()? {
out.push(row);
}
Ok(out)
}
pub struct BufferedRowSource {
iter: std::vec::IntoIter<Row>,
}
impl BufferedRowSource {
pub fn new(rows: Vec<Row>) -> Self {
Self {
iter: rows.into_iter(),
}
}
}
impl RowSource for BufferedRowSource {
fn next_row(&mut self) -> ExecResult<Option<Row>> {
Ok(self.iter.next())
}
}
pub struct ArgumentSource {
yielded: bool,
}
impl ArgumentSource {
pub fn new() -> Self {
Self { yielded: false }
}
}
impl Default for ArgumentSource {
fn default() -> Self {
Self::new()
}
}
impl RowSource for ArgumentSource {
fn next_row(&mut self) -> ExecResult<Option<Row>> {
if self.yielded {
Ok(None)
} else {
self.yielded = true;
Ok(Some(Row::new()))
}
}
}
pub(crate) struct DeadlineSource<'a> {
inner: Box<dyn RowSource + 'a>,
deadline: web_time::Instant,
tick: u32,
}
impl<'a> DeadlineSource<'a> {
pub(crate) fn wrap(
inner: Box<dyn RowSource + 'a>,
deadline: Option<web_time::Instant>,
) -> Box<dyn RowSource + 'a> {
match deadline {
Some(deadline) => Box::new(Self {
inner,
deadline,
tick: 0,
}),
None => inner,
}
}
}
impl RowSource for DeadlineSource<'_> {
fn next_row(&mut self) -> ExecResult<Option<Row>> {
self.tick = self.tick.wrapping_add(1);
if self.tick.is_multiple_of(64) && crate::cancel::deadline_reached(self.deadline) {
return Err(crate::errors::ExecutorError::QueryTimeout);
}
self.inner.next_row()
}
}