Implement FETCH clauses
This commit is contained in:
parent
4c95db254a
commit
6017d424eb
4 changed files with 79 additions and 6 deletions
|
@ -8,6 +8,7 @@ use crate::dbs::Transaction;
|
||||||
use crate::doc::Document;
|
use crate::doc::Document;
|
||||||
use crate::err::Error;
|
use crate::err::Error;
|
||||||
use crate::sql::id::Id;
|
use crate::sql::id::Id;
|
||||||
|
use crate::sql::part::Part;
|
||||||
use crate::sql::statements::create::CreateStatement;
|
use crate::sql::statements::create::CreateStatement;
|
||||||
use crate::sql::statements::delete::DeleteStatement;
|
use crate::sql::statements::delete::DeleteStatement;
|
||||||
use crate::sql::statements::insert::InsertStatement;
|
use crate::sql::statements::insert::InsertStatement;
|
||||||
|
@ -137,13 +138,11 @@ impl Iterator {
|
||||||
// Process any ORDER clause
|
// Process any ORDER clause
|
||||||
self.output_order(&ctx, opt, txn).await?;
|
self.output_order(&ctx, opt, txn).await?;
|
||||||
// Process any START clause
|
// Process any START clause
|
||||||
if let Some(v) = self.stm.start() {
|
self.output_start(&ctx, opt, txn).await?;
|
||||||
self.results = mem::take(&mut self.results).into_iter().skip(v.0).collect();
|
|
||||||
}
|
|
||||||
// Process any LIMIT clause
|
// Process any LIMIT clause
|
||||||
if let Some(v) = self.stm.limit() {
|
self.output_limit(&ctx, opt, txn).await?;
|
||||||
self.results = mem::take(&mut self.results).into_iter().take(v.0).collect();
|
// Process any FETCH clause
|
||||||
}
|
self.output_fetch(&ctx, opt, txn).await?;
|
||||||
// Output the results
|
// Output the results
|
||||||
Ok(mem::take(&mut self.results).into())
|
Ok(mem::take(&mut self.results).into())
|
||||||
}
|
}
|
||||||
|
@ -230,6 +229,70 @@ impl Iterator {
|
||||||
Ok(())
|
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"))]
|
#[cfg(not(feature = "parallel"))]
|
||||||
async fn iterate(
|
async fn iterate(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::cond::Cond;
|
use crate::sql::cond::Cond;
|
||||||
|
use crate::sql::fetch::Fetchs;
|
||||||
use crate::sql::group::Groups;
|
use crate::sql::group::Groups;
|
||||||
use crate::sql::limit::Limit;
|
use crate::sql::limit::Limit;
|
||||||
use crate::sql::order::Orders;
|
use crate::sql::order::Orders;
|
||||||
|
@ -112,6 +113,13 @@ impl Statement {
|
||||||
_ => None,
|
_ => 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
|
// Returns any START clause if specified
|
||||||
pub fn start(self: &Statement) -> Option<&Start> {
|
pub fn start(self: &Statement) -> Option<&Start> {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -30,6 +30,7 @@ impl Value {
|
||||||
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(Value::None),
|
None => Ok(Value::None),
|
||||||
},
|
},
|
||||||
|
Part::All => Ok(self.clone()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
|
|
|
@ -13,6 +13,7 @@ impl Value {
|
||||||
Some(v) => v.pick(path.next()),
|
Some(v) => v.pick(path.next()),
|
||||||
None => Value::None,
|
None => Value::None,
|
||||||
},
|
},
|
||||||
|
Part::All => self.clone(),
|
||||||
_ => Value::None,
|
_ => Value::None,
|
||||||
},
|
},
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
|
|
Loading…
Reference in a new issue