2022-04-07 10:16:52 +00:00
|
|
|
use crate::ctx::Context;
|
2022-02-06 01:14:56 +00:00
|
|
|
use crate::dbs::Options;
|
|
|
|
use crate::dbs::Statement;
|
|
|
|
use crate::doc::Document;
|
|
|
|
use crate::err::Error;
|
|
|
|
use crate::sql::idiom::Idiom;
|
|
|
|
use crate::sql::output::Output;
|
2022-07-16 22:22:23 +00:00
|
|
|
use crate::sql::paths::META;
|
2022-04-07 10:16:52 +00:00
|
|
|
use crate::sql::permission::Permission;
|
2022-02-06 01:14:56 +00:00
|
|
|
use crate::sql::value::Value;
|
|
|
|
|
2022-02-13 19:03:00 +00:00
|
|
|
impl<'a> Document<'a> {
|
2022-02-06 01:14:56 +00:00
|
|
|
pub async fn pluck(
|
|
|
|
&self,
|
2022-05-14 12:35:08 +00:00
|
|
|
ctx: &Context<'_>,
|
2022-02-06 21:06:52 +00:00
|
|
|
opt: &Options,
|
2022-05-13 20:46:56 +00:00
|
|
|
stm: &Statement<'_>,
|
2022-02-06 01:14:56 +00:00
|
|
|
) -> Result<Value, Error> {
|
|
|
|
// Ensure futures are run
|
|
|
|
let opt = &opt.futures(true);
|
2022-04-07 10:16:52 +00:00
|
|
|
// Process the desired output
|
|
|
|
let mut out = match stm.output() {
|
2022-02-06 01:14:56 +00:00
|
|
|
Some(v) => match v {
|
2022-03-06 10:58:59 +00:00
|
|
|
Output::None => Err(Error::Ignore),
|
2022-02-06 01:14:56 +00:00
|
|
|
Output::Null => Ok(Value::Null),
|
|
|
|
Output::Diff => Ok(self.initial.diff(&self.current, Idiom::default()).into()),
|
2023-06-19 18:41:13 +00:00
|
|
|
Output::After => {
|
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
self.current.compute(&ctx, opt).await
|
|
|
|
}
|
|
|
|
Output::Before => {
|
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.initial);
|
|
|
|
self.initial.compute(&ctx, opt).await
|
|
|
|
}
|
|
|
|
Output::Fields(v) => {
|
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
v.compute(&ctx, opt, false).await
|
|
|
|
}
|
2022-02-06 01:14:56 +00:00
|
|
|
},
|
|
|
|
None => match stm {
|
2023-02-22 18:04:20 +00:00
|
|
|
Statement::Live(s) => match s.expr.len() {
|
|
|
|
0 => Ok(self.initial.diff(&self.current, Idiom::default()).into()),
|
2023-06-19 18:41:13 +00:00
|
|
|
_ => {
|
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
s.expr.compute(&ctx, opt, false).await
|
|
|
|
}
|
2023-02-22 18:04:20 +00:00
|
|
|
},
|
2022-07-16 22:20:50 +00:00
|
|
|
Statement::Select(s) => {
|
2023-06-19 18:41:13 +00:00
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
s.expr.compute(&ctx, opt, s.group.is_some()).await
|
2022-07-16 22:20:50 +00:00
|
|
|
}
|
2022-04-01 09:15:52 +00:00
|
|
|
Statement::Create(_) => {
|
2023-06-19 18:41:13 +00:00
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
self.current.compute(&ctx, opt).await
|
2022-04-01 09:15:52 +00:00
|
|
|
}
|
|
|
|
Statement::Update(_) => {
|
2023-06-19 18:41:13 +00:00
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
self.current.compute(&ctx, opt).await
|
2022-04-01 09:15:52 +00:00
|
|
|
}
|
|
|
|
Statement::Relate(_) => {
|
2023-06-19 18:41:13 +00:00
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
self.current.compute(&ctx, opt).await
|
2022-04-01 09:15:52 +00:00
|
|
|
}
|
|
|
|
Statement::Insert(_) => {
|
2023-06-19 18:41:13 +00:00
|
|
|
let mut ctx = Context::new(ctx);
|
|
|
|
ctx.add_cursor_doc(&self.current);
|
|
|
|
self.current.compute(&ctx, opt).await
|
2022-04-01 09:15:52 +00:00
|
|
|
}
|
|
|
|
_ => Err(Error::Ignore),
|
2022-02-06 01:14:56 +00:00
|
|
|
},
|
2022-04-07 10:16:52 +00:00
|
|
|
}?;
|
2022-04-13 17:31:28 +00:00
|
|
|
// Check if this record exists
|
|
|
|
if self.id.is_some() {
|
2023-04-29 23:23:19 +00:00
|
|
|
// Should we run permissions checks?
|
|
|
|
if opt.perms && opt.auth.perms() {
|
2023-06-19 18:41:13 +00:00
|
|
|
// Clone transaction
|
2023-06-21 18:31:15 +00:00
|
|
|
let txn = ctx.try_clone_transaction()?;
|
2023-04-29 23:23:19 +00:00
|
|
|
// Loop through all field statements
|
2023-06-19 18:41:13 +00:00
|
|
|
for fd in self.fd(opt, &txn).await?.iter() {
|
2023-04-29 23:23:19 +00:00
|
|
|
// Loop over each field in document
|
|
|
|
for k in out.each(&fd.name).iter() {
|
|
|
|
// Process the field permissions
|
2022-10-16 21:22:13 +00:00
|
|
|
match &fd.permissions.select {
|
|
|
|
Permission::Full => (),
|
2023-06-19 18:41:13 +00:00
|
|
|
Permission::None => out.del(ctx, opt, k).await?,
|
2022-10-16 21:22:13 +00:00
|
|
|
Permission::Specific(e) => {
|
2023-02-12 11:48:11 +00:00
|
|
|
// Disable permissions
|
|
|
|
let opt = &opt.perms(false);
|
2022-10-16 21:22:13 +00:00
|
|
|
// Get the current value
|
|
|
|
let val = self.current.pick(k);
|
|
|
|
// Configure the context
|
|
|
|
let mut ctx = Context::new(ctx);
|
2023-05-06 20:49:34 +00:00
|
|
|
ctx.add_value("value", &val);
|
2023-06-19 18:41:13 +00:00
|
|
|
ctx.add_cursor_doc(&self.current);
|
2022-10-16 21:22:13 +00:00
|
|
|
// Process the PERMISSION clause
|
2023-06-19 18:41:13 +00:00
|
|
|
if !e.compute(&ctx, opt).await?.is_truthy() {
|
|
|
|
out.del(&ctx, opt, k).await?
|
2022-10-16 21:22:13 +00:00
|
|
|
}
|
2022-04-13 17:31:28 +00:00
|
|
|
}
|
2022-04-07 10:16:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-06 01:14:56 +00:00
|
|
|
}
|
2022-07-16 22:22:23 +00:00
|
|
|
// Remove metadata fields on output
|
2023-06-19 18:41:13 +00:00
|
|
|
out.del(ctx, opt, &*META).await?;
|
2022-04-07 10:16:52 +00:00
|
|
|
// Output result
|
|
|
|
Ok(out)
|
2022-02-06 01:14:56 +00:00
|
|
|
}
|
|
|
|
}
|