Allow modification of documents from subquery result sets

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-23 16:02:50 +01:00
parent 32525602e2
commit 44df5a8621
3 changed files with 47 additions and 0 deletions

View file

@ -7,6 +7,7 @@ use crate::key::thing;
use crate::sql::array::Array; use crate::sql::array::Array;
use crate::sql::id::Id; use crate::sql::id::Id;
use crate::sql::model::Model; use crate::sql::model::Model;
use crate::sql::object::Object;
use crate::sql::table::Table; use crate::sql::table::Table;
use crate::sql::thing::Thing; use crate::sql::thing::Thing;
use crate::sql::value::Value; use crate::sql::value::Value;
@ -26,6 +27,7 @@ impl Value {
) -> Result<(), Error> { ) -> Result<(), Error> {
if ctx.is_ok() { if ctx.is_ok() {
match self { match self {
Value::Object(v) => v.process(ctx, opt, txn, stm, &chn).await?,
Value::Array(v) => v.process(ctx, opt, txn, stm, &chn).await?, Value::Array(v) => v.process(ctx, opt, txn, stm, &chn).await?,
Value::Model(v) => v.process(ctx, opt, txn, stm, &chn).await?, Value::Model(v) => v.process(ctx, opt, txn, stm, &chn).await?,
Value::Thing(v) => v.process(ctx, opt, txn, stm, &chn).await?, Value::Thing(v) => v.process(ctx, opt, txn, stm, &chn).await?,
@ -51,6 +53,7 @@ impl Array {
for v in self { for v in self {
if ctx.is_ok() { if ctx.is_ok() {
match v { match v {
Value::Object(v) => v.process(ctx, opt, txn, stm, chn).await?,
Value::Array(v) => v.process(ctx, opt, txn, stm, chn).await?, Value::Array(v) => v.process(ctx, opt, txn, stm, chn).await?,
Value::Model(v) => v.process(ctx, opt, txn, stm, chn).await?, Value::Model(v) => v.process(ctx, opt, txn, stm, chn).await?,
Value::Thing(v) => v.process(ctx, opt, txn, stm, chn).await?, Value::Thing(v) => v.process(ctx, opt, txn, stm, chn).await?,
@ -63,6 +66,26 @@ impl Array {
} }
} }
impl Object {
#[cfg_attr(feature = "parallel", async_recursion)]
#[cfg_attr(not(feature = "parallel"), async_recursion(?Send))]
pub(crate) async fn process(
self,
ctx: &Context<'_>,
opt: &Options,
txn: &Transaction,
stm: &Statement<'_>,
chn: &Sender<(Option<Thing>, Value)>,
) -> Result<(), Error> {
if ctx.is_ok() {
if let Some(Value::Thing(id)) = self.get("id") {
id.clone().process(ctx, opt, txn, stm, chn).await?;
}
}
Ok(())
}
}
impl Model { impl Model {
pub(crate) async fn process( pub(crate) async fn process(
self, self,

View file

@ -8,6 +8,7 @@ use crate::key::thing;
use crate::sql::array::Array; use crate::sql::array::Array;
use crate::sql::id::Id; use crate::sql::id::Id;
use crate::sql::model::Model; use crate::sql::model::Model;
use crate::sql::object::Object;
use crate::sql::table::Table; use crate::sql::table::Table;
use crate::sql::thing::Thing; use crate::sql::thing::Thing;
use crate::sql::value::Value; use crate::sql::value::Value;
@ -26,6 +27,7 @@ impl Value {
) -> Result<(), Error> { ) -> Result<(), Error> {
if ctx.is_ok() { if ctx.is_ok() {
match self { match self {
Value::Object(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Array(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Array(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Model(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Thing(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
@ -51,6 +53,7 @@ impl Array {
for v in self.into_iter() { for v in self.into_iter() {
if ctx.is_ok() { if ctx.is_ok() {
match v { match v {
Value::Object(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Array(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Array(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Model(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Model(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
Value::Thing(v) => v.iterate(ctx, opt, txn, stm, ite).await?, Value::Thing(v) => v.iterate(ctx, opt, txn, stm, ite).await?,
@ -63,6 +66,26 @@ impl Array {
} }
} }
impl Object {
#[cfg_attr(feature = "parallel", async_recursion)]
#[cfg_attr(not(feature = "parallel"), async_recursion(?Send))]
pub(crate) async fn iterate(
self,
ctx: &Context<'_>,
opt: &Options,
txn: &Transaction,
stm: &Statement<'_>,
ite: &mut Iterator,
) -> Result<(), Error> {
if ctx.is_ok() {
if let Some(Value::Thing(id)) = self.get("id") {
id.clone().iterate(ctx, opt, txn, stm, ite).await?;
}
}
Ok(())
}
}
impl Model { impl Model {
pub(crate) async fn iterate( pub(crate) async fn iterate(
self, self,

View file

@ -1158,6 +1158,7 @@ pub fn select(i: &str) -> IResult<&str, Value> {
pub fn what(i: &str) -> IResult<&str, Value> { pub fn what(i: &str) -> IResult<&str, Value> {
alt(( alt((
map(subquery, |v| Value::Subquery(Box::new(v))),
map(function, |v| Value::Function(Box::new(v))), map(function, |v| Value::Function(Box::new(v))),
map(param, Value::Param), map(param, Value::Param),
map(model, Value::Model), map(model, Value::Model),