Implement FETCH clauses

This commit is contained in:
Tobie Morgan Hitchcock 2022-03-23 14:01:28 +00:00
parent 4c95db254a
commit 6017d424eb
4 changed files with 79 additions and 6 deletions

View file

@ -8,6 +8,7 @@ use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::id::Id;
use crate::sql::part::Part;
use crate::sql::statements::create::CreateStatement;
use crate::sql::statements::delete::DeleteStatement;
use crate::sql::statements::insert::InsertStatement;
@ -137,13 +138,11 @@ impl Iterator {
// Process any ORDER clause
self.output_order(&ctx, opt, txn).await?;
// Process any START clause
if let Some(v) = self.stm.start() {
self.results = mem::take(&mut self.results).into_iter().skip(v.0).collect();
}
self.output_start(&ctx, opt, txn).await?;
// Process any LIMIT clause
if let Some(v) = self.stm.limit() {
self.results = mem::take(&mut self.results).into_iter().take(v.0).collect();
}
self.output_limit(&ctx, opt, txn).await?;
// Process any FETCH clause
self.output_fetch(&ctx, opt, txn).await?;
// Output the results
Ok(mem::take(&mut self.results).into())
}
@ -230,6 +229,70 @@ impl Iterator {
Ok(())
}
#[inline]
async fn output_start(
&mut self,
_ctx: &Runtime,
_opt: &Options,
_txn: &Transaction,
) -> Result<(), Error> {
if let Some(v) = self.stm.start() {
self.results = mem::take(&mut self.results).into_iter().skip(v.0).collect();
}
Ok(())
}
#[inline]
async fn output_limit(
&mut self,
_ctx: &Runtime,
_opt: &Options,
_txn: &Transaction,
) -> Result<(), Error> {
if let Some(v) = self.stm.limit() {
self.results = mem::take(&mut self.results).into_iter().take(v.0).collect();
}
Ok(())
}
#[inline]
async fn output_fetch(
&mut self,
ctx: &Runtime,
opt: &Options,
txn: &Transaction,
) -> Result<(), Error> {
if let Some(fetchs) = self.stm.fetch() {
for fetch in &fetchs.0 {
// Loop over each value
for obj in &mut self.results {
// Get the value at the path
let val = obj.get(ctx, opt, txn, &fetch.fetch).await?;
// Set the value at the path
match val {
Value::Array(v) => {
// Fetch all remote records
let val = Value::Array(v).get(ctx, opt, txn, &[Part::All]).await?;
// Set the value at the path
obj.set(ctx, opt, txn, &fetch.fetch, val).await?;
}
Value::Thing(v) => {
// Fetch all remote records
let val = Value::Thing(v).get(ctx, opt, txn, &[Part::All]).await?;
// Set the value at the path
obj.set(ctx, opt, txn, &fetch.fetch, val).await?;
}
_ => {
// Set the value at the path
obj.set(ctx, opt, txn, &fetch.fetch, val).await?;
}
}
}
}
}
Ok(())
}
#[cfg(not(feature = "parallel"))]
async fn iterate(
&mut self,

View file

@ -1,4 +1,5 @@
use crate::sql::cond::Cond;
use crate::sql::fetch::Fetchs;
use crate::sql::group::Groups;
use crate::sql::limit::Limit;
use crate::sql::order::Orders;
@ -112,6 +113,13 @@ impl Statement {
_ => None,
}
}
// Returns any FETCH clause if specified
pub fn fetch(self: &Statement) -> Option<&Fetchs> {
match self {
Statement::Select(v) => v.fetch.as_ref(),
_ => None,
}
}
// Returns any START clause if specified
pub fn start(self: &Statement) -> Option<&Start> {
match self {

View file

@ -30,6 +30,7 @@ impl Value {
Some(v) => v.get(ctx, opt, txn, path.next()).await,
None => Ok(Value::None),
},
Part::All => Ok(self.clone()),
_ => Ok(Value::None),
},
// Current path part is an array

View file

@ -13,6 +13,7 @@ impl Value {
Some(v) => v.pick(path.next()),
None => Value::None,
},
Part::All => self.clone(),
_ => Value::None,
},
// Current path part is an array