Move Transaction to Context (#4096)
This commit is contained in:
parent
2b223d45ea
commit
a9e075463d
133 changed files with 1323 additions and 1879 deletions
core/src
ctx
dbs
doc
allow.rsalter.rschangefeeds.rscheck.rsclean.rscompute.rscreate.rsdelete.rsdocument.rsedges.rsempty.rsevent.rsfield.rsindex.rsinsert.rslives.rsmerge.rspluck.rsprocess.rspurge.rsrelate.rsrelation.rsreset.rsselect.rsstore.rstable.rsupdate.rs
fnc
idx
ft
planner
trees
kvs
lib.rssql
|
@ -3,13 +3,15 @@ use crate::ctx::reason::Reason;
|
|||
use crate::dbs::capabilities::FuncTarget;
|
||||
#[cfg(feature = "http")]
|
||||
use crate::dbs::capabilities::NetTarget;
|
||||
use crate::dbs::{Capabilities, Notification};
|
||||
use crate::dbs::{Capabilities, Notification, Transaction};
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::executor::QueryExecutor;
|
||||
use crate::idx::planner::{IterationStage, QueryPlanner};
|
||||
use crate::idx::trees::store::IndexStores;
|
||||
use crate::kvs;
|
||||
use crate::sql::value::Value;
|
||||
use channel::Sender;
|
||||
use futures::lock::MutexLockFuture;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{self, Debug};
|
||||
|
@ -75,6 +77,8 @@ pub struct Context<'a> {
|
|||
))]
|
||||
// The temporary directory
|
||||
temporary_directory: Option<Arc<PathBuf>>,
|
||||
// An optional transaction
|
||||
transaction: Option<Transaction>,
|
||||
}
|
||||
|
||||
impl<'a> Default for Context<'a> {
|
||||
|
@ -131,6 +135,7 @@ impl<'a> Context<'a> {
|
|||
feature = "kv-speedb"
|
||||
))]
|
||||
temporary_directory,
|
||||
transaction: None,
|
||||
};
|
||||
if let Some(timeout) = time_out {
|
||||
ctx.add_timeout(timeout)?;
|
||||
|
@ -160,6 +165,7 @@ impl<'a> Context<'a> {
|
|||
feature = "kv-speedb"
|
||||
))]
|
||||
temporary_directory: None,
|
||||
transaction: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,6 +192,7 @@ impl<'a> Context<'a> {
|
|||
feature = "kv-speedb"
|
||||
))]
|
||||
temporary_directory: parent.temporary_directory.clone(),
|
||||
transaction: parent.transaction.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,6 +253,19 @@ impl<'a> Context<'a> {
|
|||
self.iteration_stage = Some(is);
|
||||
}
|
||||
|
||||
pub(crate) fn set_transaction_mut(&mut self, txn: Transaction) {
|
||||
self.transaction = Some(txn);
|
||||
}
|
||||
|
||||
pub fn set_transaction(mut self, txn: Transaction) -> Self {
|
||||
self.transaction = Some(txn);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn tx_lock(&self) -> MutexLockFuture<'_, kvs::Transaction> {
|
||||
self.transaction.as_ref().map(|txn| txn.lock()).unwrap_or_else(|| unreachable!())
|
||||
}
|
||||
|
||||
/// Get the timeout for this operation, if any. This is useful for
|
||||
/// checking if a long job should be started or not.
|
||||
pub fn timeout(&self) -> Option<Duration> {
|
||||
|
|
|
@ -311,10 +311,10 @@ impl<'a> Executor<'a> {
|
|||
true => Err(Error::TxFailure),
|
||||
// The transaction began successfully
|
||||
false => {
|
||||
ctx.set_transaction_mut(self.txn());
|
||||
// Check the statement
|
||||
let txn = self.txn();
|
||||
match stack
|
||||
.enter(|stk| stm.compute(stk, &ctx, &opt, &txn, None))
|
||||
.enter(|stk| stm.compute(stk, &ctx, &opt, None))
|
||||
.finish()
|
||||
.await
|
||||
{
|
||||
|
@ -384,12 +384,10 @@ impl<'a> Executor<'a> {
|
|||
if let Err(err) = ctx.add_timeout(timeout) {
|
||||
Err(err)
|
||||
} else {
|
||||
let txn = self.txn();
|
||||
ctx.set_transaction_mut(self.txn());
|
||||
// Process the statement
|
||||
let res = stack
|
||||
.enter(|stk| {
|
||||
stm.compute(stk, &ctx, &opt, &txn, None)
|
||||
})
|
||||
.enter(|stk| stm.compute(stk, &ctx, &opt, None))
|
||||
.finish()
|
||||
.await;
|
||||
// Catch statement timeout
|
||||
|
@ -401,9 +399,9 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
// There is no timeout clause
|
||||
None => {
|
||||
let txn = self.txn();
|
||||
ctx.set_transaction_mut(self.txn());
|
||||
stack
|
||||
.enter(|stk| stm.compute(stk, &ctx, &opt, &txn, None))
|
||||
.enter(|stk| stm.compute(stk, &ctx, &opt, None))
|
||||
.finish()
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::plan::Explanation;
|
||||
use crate::dbs::store::MemoryCollector;
|
||||
use crate::dbs::{Options, Statement, Transaction};
|
||||
use crate::dbs::{Options, Statement};
|
||||
use crate::err::Error;
|
||||
use crate::sql::function::OptimisedAggregate;
|
||||
use crate::sql::value::{TryAdd, TryDiv, Value};
|
||||
|
@ -63,7 +63,6 @@ impl GroupsCollector {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
obj: Value,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -82,7 +81,7 @@ impl GroupsCollector {
|
|||
.grp
|
||||
.entry(arr)
|
||||
.or_insert_with(|| self.base.iter().map(|a| a.new_instance()).collect());
|
||||
Self::pushes(stk, ctx, opt, txn, agr, &self.idioms, obj).await?
|
||||
Self::pushes(stk, ctx, opt, agr, &self.idioms, obj).await?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -91,14 +90,13 @@ impl GroupsCollector {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
agrs: &mut [Aggregator],
|
||||
idioms: &[Idiom],
|
||||
obj: Value,
|
||||
) -> Result<(), Error> {
|
||||
for (agr, idiom) in agrs.iter_mut().zip(idioms) {
|
||||
let val = stk.run(|stk| obj.get(stk, ctx, opt, txn, None, idiom)).await?;
|
||||
agr.push(stk, ctx, opt, txn, val).await?;
|
||||
let val = stk.run(|stk| obj.get(stk, ctx, opt, None, idiom)).await?;
|
||||
agr.push(stk, ctx, opt, val).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -112,7 +110,6 @@ impl GroupsCollector {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<MemoryCollector, Error> {
|
||||
let mut results = MemoryCollector::default();
|
||||
|
@ -143,18 +140,16 @@ impl GroupsCollector {
|
|||
let x = if matches!(a, OptimisedAggregate::None) {
|
||||
// The aggregation is not optimised, let's compute it with the values
|
||||
let vals = agr.take();
|
||||
f.aggregate(vals)
|
||||
.compute(stk, ctx, opt, txn, None)
|
||||
.await?
|
||||
f.aggregate(vals).compute(stk, ctx, opt, None).await?
|
||||
} else {
|
||||
// The aggregation is optimised, just get the value
|
||||
agr.compute(a)?
|
||||
};
|
||||
obj.set(stk, ctx, opt, txn, idiom.as_ref(), x).await?;
|
||||
obj.set(stk, ctx, opt, idiom.as_ref(), x).await?;
|
||||
}
|
||||
_ => {
|
||||
let x = agr.take().first();
|
||||
obj.set(stk, ctx, opt, txn, idiom.as_ref(), x).await?;
|
||||
obj.set(stk, ctx, opt, idiom.as_ref(), x).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -263,14 +258,13 @@ impl Aggregator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
val: Value,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(ref mut c) = self.count {
|
||||
*c += 1;
|
||||
}
|
||||
if let Some((ref f, ref mut c)) = self.count_function {
|
||||
if f.aggregate(val.clone()).compute(stk, ctx, opt, txn, None).await?.is_truthy() {
|
||||
if f.aggregate(val.clone()).compute(stk, ctx, opt, None).await?.is_truthy() {
|
||||
*c += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use crate::dbs::distinct::AsyncDistinct;
|
|||
use crate::dbs::distinct::SyncDistinct;
|
||||
use crate::dbs::plan::Plan;
|
||||
use crate::dbs::result::Results;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::iterators::{IteratorRecord, IteratorRef};
|
||||
|
@ -96,7 +96,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
val: Value,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -106,7 +105,7 @@ impl Iterator {
|
|||
// There is a data clause so fetch a record id
|
||||
Some(data) => match stm {
|
||||
Statement::Create(_) => {
|
||||
let id = match data.rid(stk, ctx, opt, txn).await? {
|
||||
let id = match data.rid(stk, ctx, opt).await? {
|
||||
// Generate a new id from the id field
|
||||
Some(id) => id.generate(&v, false)?,
|
||||
// Generate a new random table id
|
||||
|
@ -135,7 +134,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
// Check to see the type of the id
|
||||
match id {
|
||||
// The id is a match, so don't error
|
||||
|
@ -163,7 +162,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
return Err(Error::IdMismatch {
|
||||
value: id.to_string(),
|
||||
});
|
||||
|
@ -184,7 +183,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
return Err(Error::IdMismatch {
|
||||
value: id.to_string(),
|
||||
});
|
||||
|
@ -203,7 +202,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
return Err(Error::IdMismatch {
|
||||
value: id.to_string(),
|
||||
});
|
||||
|
@ -216,7 +215,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
return Err(Error::IdMismatch {
|
||||
value: id.to_string(),
|
||||
});
|
||||
|
@ -239,7 +238,7 @@ impl Iterator {
|
|||
// Check if there is a data clause
|
||||
if let Some(data) = stm.data() {
|
||||
// Check if there is an id field specified
|
||||
if let Some(id) = data.rid(stk, ctx, opt, txn).await? {
|
||||
if let Some(id) = data.rid(stk, ctx, opt).await? {
|
||||
return Err(Error::IdMismatch {
|
||||
value: id.to_string(),
|
||||
});
|
||||
|
@ -282,7 +281,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Log the statement
|
||||
|
@ -291,9 +289,9 @@ impl Iterator {
|
|||
let mut cancel_ctx = Context::new(ctx);
|
||||
self.run = cancel_ctx.add_cancel();
|
||||
// Process the query LIMIT clause
|
||||
self.setup_limit(stk, &cancel_ctx, opt, txn, stm).await?;
|
||||
self.setup_limit(stk, &cancel_ctx, opt, stm).await?;
|
||||
// Process the query START clause
|
||||
self.setup_start(stk, &cancel_ctx, opt, txn, stm).await?;
|
||||
self.setup_start(stk, &cancel_ctx, opt, stm).await?;
|
||||
// Prepare the results with possible optimisations on groups
|
||||
self.results = self.results.prepare(
|
||||
#[cfg(any(
|
||||
|
@ -317,20 +315,20 @@ impl Iterator {
|
|||
let is_last = matches!(s, IterationStage::Iterate(_));
|
||||
cancel_ctx.set_iteration_stage(s);
|
||||
if !is_last {
|
||||
self.clone().iterate(stk, &cancel_ctx, opt, txn, stm).await?;
|
||||
self.clone().iterate(stk, &cancel_ctx, opt, stm).await?;
|
||||
};
|
||||
}
|
||||
}
|
||||
self.iterate(stk, &cancel_ctx, opt, txn, stm).await?;
|
||||
self.iterate(stk, &cancel_ctx, opt, stm).await?;
|
||||
// Return any document errors
|
||||
if let Some(e) = self.error.take() {
|
||||
return Err(e);
|
||||
}
|
||||
// Process any SPLIT clause
|
||||
self.output_split(stk, ctx, opt, txn, stm).await?;
|
||||
self.output_split(stk, ctx, opt, stm).await?;
|
||||
// Process any GROUP clause
|
||||
if let Results::Groups(g) = &mut self.results {
|
||||
self.results = Results::Memory(g.output(stk, ctx, opt, txn, stm).await?);
|
||||
self.results = Results::Memory(g.output(stk, ctx, opt, stm).await?);
|
||||
}
|
||||
|
||||
// Process any ORDER clause
|
||||
|
@ -345,7 +343,7 @@ impl Iterator {
|
|||
e.add_fetch(self.results.len());
|
||||
} else {
|
||||
// Process any FETCH clause
|
||||
self.output_fetch(stk, ctx, opt, txn, stm).await?;
|
||||
self.output_fetch(stk, ctx, opt, stm).await?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,11 +368,10 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(v) = stm.limit() {
|
||||
self.limit = Some(v.process(stk, ctx, opt, txn, None).await?);
|
||||
self.limit = Some(v.process(stk, ctx, opt, None).await?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -385,11 +382,10 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(v) = stm.start() {
|
||||
self.start = Some(v.process(stk, ctx, opt, txn, None).await?);
|
||||
self.start = Some(v.process(stk, ctx, opt, None).await?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -400,7 +396,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(splits) = stm.split() {
|
||||
|
@ -419,18 +414,18 @@ impl Iterator {
|
|||
// Make a copy of object
|
||||
let mut obj = obj.clone();
|
||||
// Set the value at the path
|
||||
obj.set(stk, ctx, opt, txn, split, val).await?;
|
||||
obj.set(stk, ctx, opt, split, val).await?;
|
||||
// Add the object to the results
|
||||
self.results.push(stk, ctx, opt, txn, stm, obj).await?;
|
||||
self.results.push(stk, ctx, opt, stm, obj).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Make a copy of object
|
||||
let mut obj = obj.clone();
|
||||
// Set the value at the path
|
||||
obj.set(stk, ctx, opt, txn, split, val).await?;
|
||||
obj.set(stk, ctx, opt, split, val).await?;
|
||||
// Add the object to the results
|
||||
self.results.push(stk, ctx, opt, txn, stm, obj).await?;
|
||||
self.results.push(stk, ctx, opt, stm, obj).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +440,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(fetchs) = stm.fetch() {
|
||||
|
@ -454,7 +448,7 @@ impl Iterator {
|
|||
// Loop over each result value
|
||||
for obj in &mut values {
|
||||
// Fetch the value at the path
|
||||
stk.run(|stk| obj.fetch(stk, ctx, opt, txn, fetch)).await?;
|
||||
stk.run(|stk| obj.fetch(stk, ctx, opt, fetch)).await?;
|
||||
}
|
||||
self.results = values.into();
|
||||
}
|
||||
|
@ -468,7 +462,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Prevent deep recursion
|
||||
|
@ -477,7 +470,7 @@ impl Iterator {
|
|||
let mut distinct = SyncDistinct::new(ctx);
|
||||
// Process all prepared values
|
||||
for v in mem::take(&mut self.entries) {
|
||||
v.iterate(stk, ctx, opt, txn, stm, self, distinct.as_mut()).await?;
|
||||
v.iterate(stk, ctx, opt, stm, self, distinct.as_mut()).await?;
|
||||
}
|
||||
// Everything processed ok
|
||||
Ok(())
|
||||
|
@ -489,7 +482,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Prevent deep recursion
|
||||
|
@ -502,7 +494,7 @@ impl Iterator {
|
|||
let mut distinct = SyncDistinct::new(ctx);
|
||||
// Process all prepared values
|
||||
for v in mem::take(&mut self.entries) {
|
||||
v.iterate(stk, ctx, opt, txn, stm, self, distinct.as_mut()).await?;
|
||||
v.iterate(stk, ctx, opt, stm, self, distinct.as_mut()).await?;
|
||||
}
|
||||
// Everything processed ok
|
||||
Ok(())
|
||||
|
@ -530,7 +522,7 @@ impl Iterator {
|
|||
let mut stack = TreeStack::new();
|
||||
stack
|
||||
.enter(|stk| {
|
||||
v.channel(stk, ctx, opt, txn, stm, chn_clone, distinct_clone)
|
||||
v.channel(stk, ctx, opt, stm, chn_clone, distinct_clone)
|
||||
})
|
||||
.finish()
|
||||
.await
|
||||
|
@ -551,9 +543,7 @@ impl Iterator {
|
|||
e.spawn(async move {
|
||||
let mut stack = TreeStack::new();
|
||||
stack
|
||||
.enter(|stk| {
|
||||
Document::compute(stk, ctx, opt, txn, stm, chn_clone, pro)
|
||||
})
|
||||
.enter(|stk| Document::compute(stk, ctx, opt, stm, chn_clone, pro))
|
||||
.finish()
|
||||
.await
|
||||
})
|
||||
|
@ -567,7 +557,7 @@ impl Iterator {
|
|||
let aproc = async {
|
||||
// Process all processed values
|
||||
while let Ok(r) = vals.recv().await {
|
||||
self.result(stk, ctx, opt, txn, stm, r).await;
|
||||
self.result(stk, ctx, opt, stm, r).await;
|
||||
}
|
||||
// Shutdown the executor
|
||||
let _ = end.send(()).await;
|
||||
|
@ -590,14 +580,13 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
pro: Processed,
|
||||
) {
|
||||
// Process the document
|
||||
let res = stk.run(|stk| Document::process(stk, ctx, opt, txn, stm, pro)).await;
|
||||
let res = stk.run(|stk| Document::process(stk, ctx, opt, stm, pro)).await;
|
||||
// Process the result
|
||||
self.result(stk, ctx, opt, txn, stm, res).await;
|
||||
self.result(stk, ctx, opt, stm, res).await;
|
||||
}
|
||||
|
||||
/// Accept a processed record result
|
||||
|
@ -606,7 +595,6 @@ impl Iterator {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
res: Result<Value, Error>,
|
||||
) {
|
||||
|
@ -621,7 +609,7 @@ impl Iterator {
|
|||
return;
|
||||
}
|
||||
Ok(v) => {
|
||||
if let Err(e) = self.results.push(stk, ctx, opt, txn, stm, v).await {
|
||||
if let Err(e) = self.results.push(stk, ctx, opt, stm, v).await {
|
||||
self.error = Some(e);
|
||||
self.run.cancel();
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use super::capabilities::Capabilities;
|
||||
use crate::cnf::MAX_COMPUTATION_DEPTH;
|
||||
use crate::dbs::Notification;
|
||||
use crate::err::Error;
|
||||
|
@ -47,8 +46,6 @@ pub struct Options {
|
|||
pub projections: bool,
|
||||
/// The channel over which we send notifications
|
||||
pub sender: Option<Sender<Notification>>,
|
||||
/// Datastore capabilities
|
||||
pub capabilities: Arc<Capabilities>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -94,7 +91,6 @@ impl Options {
|
|||
auth_enabled: true,
|
||||
sender: None,
|
||||
auth: Arc::new(Auth::default()),
|
||||
capabilities: Arc::new(Capabilities::default()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +115,7 @@ impl Options {
|
|||
/// instances when there is doubt.
|
||||
pub fn with_required(
|
||||
mut self,
|
||||
node_id: uuid::Uuid,
|
||||
node_id: Uuid,
|
||||
ns: Option<Arc<str>>,
|
||||
db: Option<Arc<str>>,
|
||||
auth: Arc<Auth>,
|
||||
|
@ -215,12 +211,6 @@ impl Options {
|
|||
self
|
||||
}
|
||||
|
||||
/// Create a new Options object with the given Capabilities
|
||||
pub fn with_capabilities(mut self, capabilities: Arc<Capabilities>) -> Self {
|
||||
self.capabilities = capabilities;
|
||||
self
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
|
||||
/// Create a new Options object for a subquery
|
||||
|
@ -228,7 +218,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -242,7 +231,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force,
|
||||
|
@ -255,7 +243,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -269,7 +256,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -283,7 +269,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -297,7 +282,6 @@ impl Options {
|
|||
Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -310,7 +294,6 @@ impl Options {
|
|||
pub fn new_with_sender(&self, sender: Sender<Notification>) -> Self {
|
||||
Self {
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
@ -340,7 +323,6 @@ impl Options {
|
|||
Ok(Self {
|
||||
sender: self.sender.clone(),
|
||||
auth: self.auth.clone(),
|
||||
capabilities: self.capabilities.clone(),
|
||||
ns: self.ns.clone(),
|
||||
db: self.db.clone(),
|
||||
force: self.force.clone(),
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::ctx::Context;
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::dbs::distinct::AsyncDistinct;
|
||||
use crate::dbs::distinct::SyncDistinct;
|
||||
use crate::dbs::{Iterable, Iterator, Operable, Options, Processed, Statement, Transaction};
|
||||
use crate::dbs::{Iterable, Iterator, Operable, Options, Processed, Statement};
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::iterators::{CollectorRecord, IteratorRef, ThingIterator};
|
||||
use crate::idx::planner::IterationStage;
|
||||
|
@ -19,38 +19,34 @@ use std::ops::Bound;
|
|||
use std::vec;
|
||||
|
||||
impl Iterable {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn iterate(
|
||||
self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
ite: &mut Iterator,
|
||||
dis: Option<&mut SyncDistinct>,
|
||||
) -> Result<(), Error> {
|
||||
if self.iteration_stage_check(ctx) {
|
||||
Processor::Iterator(dis, ite).process_iterable(stk, ctx, opt, txn, stm, self).await
|
||||
Processor::Iterator(dis, ite).process_iterable(stk, ctx, opt, stm, self).await
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn channel(
|
||||
self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
chn: Sender<Processed>,
|
||||
dis: Option<AsyncDistinct>,
|
||||
) -> Result<(), Error> {
|
||||
if self.iteration_stage_check(ctx) {
|
||||
Processor::Channel(dis, chn).process_iterable(stk, ctx, opt, txn, stm, self).await
|
||||
Processor::Channel(dis, chn).process_iterable(stk, ctx, opt, stm, self).await
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -85,7 +81,6 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
pro: Processed,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -97,7 +92,7 @@ impl<'a> Processor<'a> {
|
|||
false
|
||||
};
|
||||
if !is_processed {
|
||||
ite.process(stk, ctx, opt, txn, stm, pro).await;
|
||||
ite.process(stk, ctx, opt, stm, pro).await;
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -120,15 +115,14 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
iterable: Iterable,
|
||||
) -> Result<(), Error> {
|
||||
if ctx.is_ok() {
|
||||
match iterable {
|
||||
Iterable::Value(v) => self.process_value(stk, ctx, opt, txn, stm, v).await?,
|
||||
Iterable::Thing(v) => self.process_thing(stk, ctx, opt, txn, stm, v).await?,
|
||||
Iterable::Defer(v) => self.process_defer(stk, ctx, opt, txn, stm, v).await?,
|
||||
Iterable::Value(v) => self.process_value(stk, ctx, opt, stm, v).await?,
|
||||
Iterable::Thing(v) => self.process_thing(stk, ctx, opt, stm, v).await?,
|
||||
Iterable::Defer(v) => self.process_defer(stk, ctx, opt, stm, v).await?,
|
||||
Iterable::Table(v) => {
|
||||
if let Some(qp) = ctx.get_query_planner() {
|
||||
if let Some(exe) = qp.get_query_executor(&v.0) {
|
||||
|
@ -136,13 +130,13 @@ impl<'a> Processor<'a> {
|
|||
// Avoiding search in the hashmap of the query planner for each doc
|
||||
let mut ctx = Context::new(ctx);
|
||||
ctx.set_query_executor(exe.clone());
|
||||
return self.process_table(stk, &ctx, opt, txn, stm, &v).await;
|
||||
return self.process_table(stk, &ctx, opt, stm, &v).await;
|
||||
}
|
||||
}
|
||||
self.process_table(stk, ctx, opt, txn, stm, &v).await?
|
||||
self.process_table(stk, ctx, opt, stm, &v).await?
|
||||
}
|
||||
Iterable::Range(v) => self.process_range(stk, ctx, opt, txn, stm, v).await?,
|
||||
Iterable::Edges(e) => self.process_edge(stk, ctx, opt, txn, stm, e).await?,
|
||||
Iterable::Range(v) => self.process_range(stk, ctx, opt, stm, v).await?,
|
||||
Iterable::Edges(e) => self.process_edge(stk, ctx, opt, stm, e).await?,
|
||||
Iterable::Index(t, irf) => {
|
||||
if let Some(qp) = ctx.get_query_planner() {
|
||||
if let Some(exe) = qp.get_query_executor(&t.0) {
|
||||
|
@ -150,16 +144,16 @@ impl<'a> Processor<'a> {
|
|||
// Avoiding search in the hashmap of the query planner for each doc
|
||||
let mut ctx = Context::new(ctx);
|
||||
ctx.set_query_executor(exe.clone());
|
||||
return self.process_index(stk, &ctx, opt, txn, stm, &t, irf).await;
|
||||
return self.process_index(stk, &ctx, opt, stm, &t, irf).await;
|
||||
}
|
||||
}
|
||||
self.process_index(stk, ctx, opt, txn, stm, &t, irf).await?
|
||||
self.process_index(stk, ctx, opt, stm, &t, irf).await?
|
||||
}
|
||||
Iterable::Mergeable(v, o) => {
|
||||
self.process_mergeable(stk, ctx, opt, txn, stm, v, o).await?
|
||||
self.process_mergeable(stk, ctx, opt, stm, v, o).await?
|
||||
}
|
||||
Iterable::Relatable(f, v, w) => {
|
||||
self.process_relatable(stk, ctx, opt, txn, stm, f, v, w).await?
|
||||
self.process_relatable(stk, ctx, opt, stm, f, v, w).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +165,6 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: Value,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -182,7 +175,7 @@ impl<'a> Processor<'a> {
|
|||
val: Operable::Value(v),
|
||||
};
|
||||
// Process the document record
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await
|
||||
self.process(stk, ctx, opt, stm, pro).await
|
||||
}
|
||||
|
||||
async fn process_thing(
|
||||
|
@ -190,15 +183,14 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: Thing,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
// Fetch the data from the store
|
||||
let key = thing::new(opt.ns(), opt.db(), &v.tb, &v.id);
|
||||
let val = txn.clone().lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
// Parse the data from the store
|
||||
let val = Operable::Value(match val {
|
||||
Some(v) => Value::from(v),
|
||||
|
@ -210,7 +202,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
// Everything ok
|
||||
Ok(())
|
||||
}
|
||||
|
@ -220,39 +212,36 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: Thing,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
// Process the document record
|
||||
let pro = Processed {
|
||||
rid: Some(v),
|
||||
ir: None,
|
||||
val: Operable::Value(Value::None),
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
// Everything ok
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn process_mergeable(
|
||||
&mut self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: Thing,
|
||||
o: Value,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
// Fetch the data from the store
|
||||
let key = thing::new(opt.ns(), opt.db(), &v.tb, &v.id);
|
||||
let val = txn.clone().lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
// Parse the data from the store
|
||||
let x = match val {
|
||||
Some(v) => Value::from(v),
|
||||
|
@ -266,7 +255,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
// Everything ok
|
||||
Ok(())
|
||||
}
|
||||
|
@ -277,17 +266,16 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
f: Thing,
|
||||
v: Thing,
|
||||
w: Thing,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
// Fetch the data from the store
|
||||
let key = thing::new(opt.ns(), opt.db(), &v.tb, &v.id);
|
||||
let val = txn.clone().lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
// Parse the data from the store
|
||||
let x = match val {
|
||||
Some(v) => Value::from(v),
|
||||
|
@ -301,7 +289,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
// Everything ok
|
||||
Ok(())
|
||||
}
|
||||
|
@ -311,12 +299,11 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: &Table,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), v, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), v, opt.strict).await?;
|
||||
// Prepare the start and end keys
|
||||
let beg = thing::prefix(opt.ns(), opt.db(), v);
|
||||
let end = thing::suffix(opt.ns(), opt.db(), v);
|
||||
|
@ -328,7 +315,7 @@ impl<'a> Processor<'a> {
|
|||
break;
|
||||
}
|
||||
// Get the next batch of key-value entries
|
||||
let res = txn.clone().lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
let res = ctx.tx_lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
next_page = res.next_page;
|
||||
let res = res.values;
|
||||
// If no results then break
|
||||
|
@ -353,7 +340,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -366,12 +353,11 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
v: Range,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &v.tb, opt.strict).await?;
|
||||
// Prepare the range start key
|
||||
let beg = match &v.beg {
|
||||
Bound::Unbounded => thing::prefix(opt.ns(), opt.db(), &v.tb),
|
||||
|
@ -399,7 +385,7 @@ impl<'a> Processor<'a> {
|
|||
if ctx.is_done() {
|
||||
break;
|
||||
}
|
||||
let res = txn.clone().lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
let res = ctx.tx_lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
next_page = res.next_page;
|
||||
// Get the next batch of key-value entries
|
||||
let res = res.values;
|
||||
|
@ -425,7 +411,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -438,7 +424,6 @@ impl<'a> Processor<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
e: Edges,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -520,7 +505,7 @@ impl<'a> Processor<'a> {
|
|||
break;
|
||||
}
|
||||
// Get the next batch key-value entries
|
||||
let res = txn.lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
let res = ctx.tx_lock().await.scan_paged(page, PROCESSOR_BATCH_SIZE).await?;
|
||||
next_page = res.next_page;
|
||||
let res = res.values;
|
||||
// If there are key-value entries then fetch them
|
||||
|
@ -537,7 +522,7 @@ impl<'a> Processor<'a> {
|
|||
let gra: graph::Graph = graph::Graph::decode(&k)?;
|
||||
// Fetch the data from the store
|
||||
let key = thing::new(opt.ns(), opt.db(), gra.ft, &gra.fk);
|
||||
let val = txn.lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
let rid = Thing::from((gra.ft, gra.fk));
|
||||
// Parse the data from the store
|
||||
let val = Operable::Value(match val {
|
||||
|
@ -550,7 +535,7 @@ impl<'a> Processor<'a> {
|
|||
ir: None,
|
||||
val,
|
||||
};
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -559,23 +544,21 @@ impl<'a> Processor<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn process_index(
|
||||
&mut self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
table: &Table,
|
||||
irf: IteratorRef,
|
||||
) -> Result<(), Error> {
|
||||
// Check that the table exists
|
||||
txn.lock().await.check_ns_db_tb(opt.ns(), opt.db(), &table.0, opt.strict).await?;
|
||||
ctx.tx_lock().await.check_ns_db_tb(opt.ns(), opt.db(), &table.0, opt.strict).await?;
|
||||
if let Some(exe) = ctx.get_query_executor() {
|
||||
if let Some(mut iterator) = exe.new_iterator(opt, irf).await? {
|
||||
// Get the first batch
|
||||
let mut to_process = Self::next_batch(ctx, opt, txn, &mut iterator).await?;
|
||||
let mut to_process = Self::next_batch(ctx, opt, &mut iterator).await?;
|
||||
|
||||
while !to_process.is_empty() {
|
||||
// Check if the context is finished
|
||||
|
@ -585,10 +568,10 @@ impl<'a> Processor<'a> {
|
|||
// Process the records
|
||||
// TODO: par_iter
|
||||
for pro in to_process {
|
||||
self.process(stk, ctx, opt, txn, stm, pro).await?;
|
||||
self.process(stk, ctx, opt, stm, pro).await?;
|
||||
}
|
||||
// Get the next batch
|
||||
to_process = Self::next_batch(ctx, opt, txn, &mut iterator).await?;
|
||||
to_process = Self::next_batch(ctx, opt, &mut iterator).await?;
|
||||
}
|
||||
// Everything ok
|
||||
return Ok(());
|
||||
|
@ -606,10 +589,9 @@ impl<'a> Processor<'a> {
|
|||
async fn next_batch(
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
iterator: &mut ThingIterator,
|
||||
) -> Result<Vec<Processed>, Error> {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let records: Vec<CollectorRecord> =
|
||||
iterator.next_batch(ctx, &mut tx, PROCESSOR_BATCH_SIZE).await?;
|
||||
let mut to_process = Vec::with_capacity(records.len());
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::dbs::plan::Explanation;
|
|||
))]
|
||||
use crate::dbs::store::file_store::FileCollector;
|
||||
use crate::dbs::store::MemoryCollector;
|
||||
use crate::dbs::{Options, Statement, Transaction};
|
||||
use crate::dbs::{Options, Statement};
|
||||
use crate::err::Error;
|
||||
use crate::sql::{Orders, Value};
|
||||
use reblessive::tree::Stk;
|
||||
|
@ -73,7 +73,6 @@ impl Results {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
val: Value,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -95,7 +94,7 @@ impl Results {
|
|||
e.push(val)?;
|
||||
}
|
||||
Self::Groups(g) => {
|
||||
g.push(stk, ctx, opt, txn, stm, val).await?;
|
||||
g.push(stk, ctx, opt, stm, val).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::iam::Auth;
|
||||
use crate::iam::Role;
|
||||
use crate::kvs::{Datastore, LockType::*, TransactionType::*};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub async fn mock<'a>() -> (Context<'a>, Options, Transaction) {
|
||||
let ctx = Context::default();
|
||||
pub async fn mock<'a>() -> (Context<'a>, Options) {
|
||||
let opt = Options::default().with_auth(Arc::new(Auth::for_root(Role::Owner)));
|
||||
let kvs = Datastore::new("memory").await.unwrap();
|
||||
let txn = kvs.transaction(Write, Optimistic).await.unwrap().rollback_and_ignore().enclose();
|
||||
(ctx, opt, txn)
|
||||
let ctx = Context::default().set_transaction(txn);
|
||||
(ctx, opt)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::permission::Permission;
|
||||
|
@ -12,7 +12,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if this record exists
|
||||
|
@ -20,7 +19,7 @@ impl<'a> Document<'a> {
|
|||
// Should we run permissions checks?
|
||||
if opt.check_perms(stm.into()) {
|
||||
// Get the table
|
||||
let tb = self.tb(opt, txn).await?;
|
||||
let tb = self.tb(ctx, opt).await?;
|
||||
// Get the permission clause
|
||||
let perms = if stm.is_delete() {
|
||||
&tb.permissions.delete
|
||||
|
@ -44,7 +43,6 @@ impl<'a> Document<'a> {
|
|||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
Some(match stm.is_delete() {
|
||||
true => &self.initial,
|
||||
false => &self.current,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Workable;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::data::Data;
|
||||
|
@ -15,7 +15,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the record id
|
||||
|
@ -26,57 +25,39 @@ impl<'a> Document<'a> {
|
|||
if let Some(v) = stm.data() {
|
||||
match v {
|
||||
Data::PatchExpression(data) => {
|
||||
let data = data.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let data = data.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
self.current.doc.to_mut().patch(data)?
|
||||
}
|
||||
Data::MergeExpression(data) => {
|
||||
let data = data.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let data = data.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
self.current.doc.to_mut().merge(data)?
|
||||
}
|
||||
Data::ReplaceExpression(data) => {
|
||||
let data = data.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let data = data.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
self.current.doc.to_mut().replace(data)?
|
||||
}
|
||||
Data::ContentExpression(data) => {
|
||||
let data = data.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let data = data.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
self.current.doc.to_mut().replace(data)?
|
||||
}
|
||||
Data::SetExpression(x) => {
|
||||
for x in x.iter() {
|
||||
let v = x.2.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let v = x.2.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
match x.1 {
|
||||
Operator::Equal => match v {
|
||||
Value::None => {
|
||||
self.current.doc.to_mut().del(stk, ctx, opt, txn, &x.0).await?
|
||||
}
|
||||
_ => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.set(stk, ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().del(stk, ctx, opt, &x.0).await?
|
||||
}
|
||||
_ => self.current.doc.to_mut().set(stk, ctx, opt, &x.0, v).await?,
|
||||
},
|
||||
Operator::Inc => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.increment(stk, ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().increment(stk, ctx, opt, &x.0, v).await?
|
||||
}
|
||||
Operator::Dec => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.decrement(stk, ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().decrement(stk, ctx, opt, &x.0, v).await?
|
||||
}
|
||||
Operator::Ext => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.extend(stk, ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().extend(stk, ctx, opt, &x.0, v).await?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -84,7 +65,7 @@ impl<'a> Document<'a> {
|
|||
}
|
||||
Data::UnsetExpression(i) => {
|
||||
for i in i.iter() {
|
||||
self.current.doc.to_mut().del(stk, ctx, opt, txn, i).await?
|
||||
self.current.doc.to_mut().del(stk, ctx, opt, i).await?
|
||||
}
|
||||
}
|
||||
Data::UpdateExpression(x) => {
|
||||
|
@ -96,40 +77,22 @@ impl<'a> Document<'a> {
|
|||
}
|
||||
// Process ON DUPLICATE KEY clause
|
||||
for x in x.iter() {
|
||||
let v = x.2.compute(stk, &ctx, opt, txn, Some(&self.current)).await?;
|
||||
let v = x.2.compute(stk, &ctx, opt, Some(&self.current)).await?;
|
||||
match x.1 {
|
||||
Operator::Equal => match v {
|
||||
Value::None => {
|
||||
self.current.doc.to_mut().del(stk, &ctx, opt, txn, &x.0).await?
|
||||
}
|
||||
_ => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.set(stk, &ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().del(stk, &ctx, opt, &x.0).await?
|
||||
}
|
||||
_ => self.current.doc.to_mut().set(stk, &ctx, opt, &x.0, v).await?,
|
||||
},
|
||||
Operator::Inc => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.increment(stk, &ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().increment(stk, &ctx, opt, &x.0, v).await?
|
||||
}
|
||||
Operator::Dec => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.decrement(stk, &ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().decrement(stk, &ctx, opt, &x.0, v).await?
|
||||
}
|
||||
Operator::Ext => {
|
||||
self.current
|
||||
.doc
|
||||
.to_mut()
|
||||
.extend(stk, &ctx, opt, txn, &x.0, v)
|
||||
.await?
|
||||
self.current.doc.to_mut().extend(stk, &ctx, opt, &x.0, v).await?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
||||
impl<'a> Document<'a> {
|
||||
pub async fn changefeeds(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if changed
|
||||
|
@ -18,11 +16,9 @@ impl<'a> Document<'a> {
|
|||
return Ok(());
|
||||
}
|
||||
//
|
||||
let tb = self.tb(opt, txn).await?;
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
let tb = self.tb(ctx, opt).await?;
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the database and the table for the record
|
||||
let db = run.add_and_cache_db(opt.ns(), opt.db(), opt.strict).await?;
|
||||
// Check if changefeeds are enabled
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::{CursorDoc, Document};
|
||||
use crate::err::Error;
|
||||
use crate::sql::Cond;
|
||||
|
@ -12,24 +12,22 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
Self::check_cond(stk, ctx, opt, txn, stm.conds(), &self.current).await
|
||||
Self::check_cond(stk, ctx, opt, stm.conds(), &self.current).await
|
||||
}
|
||||
|
||||
pub(crate) async fn check_cond(
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
cond: Option<&Cond>,
|
||||
doc: &CursorDoc<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check where condition
|
||||
if let Some(cond) = cond {
|
||||
// Check if the expression is truthy
|
||||
if !cond.compute(stk, ctx, opt, txn, Some(doc)).await?.is_truthy() {
|
||||
if !cond.compute(stk, ctx, opt, Some(doc)).await?.is_truthy() {
|
||||
// Ignore this document
|
||||
return Err(Error::Ignore);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::idiom::Idiom;
|
||||
|
@ -12,17 +12,16 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the table
|
||||
let tb = self.tb(opt, txn).await?;
|
||||
let tb = self.tb(ctx, opt).await?;
|
||||
// This table is schemafull
|
||||
if tb.full {
|
||||
// Create a vector to store the keys
|
||||
let mut keys: Vec<Idiom> = vec![];
|
||||
// Loop through all field statements
|
||||
for fd in self.fd(opt, txn).await?.iter() {
|
||||
for fd in self.fd(ctx, opt).await?.iter() {
|
||||
// Is this a schemaless field?
|
||||
match fd.flex {
|
||||
false => {
|
||||
|
@ -47,7 +46,7 @@ impl<'a> Document<'a> {
|
|||
fd if fd.is_in() => continue,
|
||||
fd if fd.is_out() => continue,
|
||||
fd if fd.is_meta() => continue,
|
||||
fd => self.current.doc.to_mut().del(stk, ctx, opt, txn, fd).await?,
|
||||
fd => self.current.doc.to_mut().del(stk, ctx, opt, fd).await?,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Operable;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Workable;
|
||||
use crate::dbs::{Operable, Transaction};
|
||||
use crate::dbs::{Options, Processed};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
@ -15,7 +15,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
chn: Sender<Result<Value, Error>>,
|
||||
mut pro: Processed,
|
||||
|
@ -36,12 +35,12 @@ impl<'a> Document<'a> {
|
|||
let mut doc = Document::new(pro.rid.as_ref(), pro.ir.as_ref(), &ins.0, ins.1);
|
||||
// Process the statement
|
||||
let res = match stm {
|
||||
Statement::Select(_) => doc.select(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Create(_) => doc.create(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Update(_) => doc.update(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Relate(_) => doc.relate(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Delete(_) => doc.delete(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Insert(_) => doc.insert(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Select(_) => doc.select(stk, ctx, opt, stm).await,
|
||||
Statement::Create(_) => doc.create(stk, ctx, opt, stm).await,
|
||||
Statement::Update(_) => doc.update(stk, ctx, opt, stm).await,
|
||||
Statement::Relate(_) => doc.relate(stk, ctx, opt, stm).await,
|
||||
Statement::Delete(_) => doc.delete(stk, ctx, opt, stm).await,
|
||||
Statement::Insert(_) => doc.insert(stk, ctx, opt, stm).await,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Check the result
|
||||
|
@ -52,7 +51,7 @@ impl<'a> Document<'a> {
|
|||
Err(Error::RetryWithId(v)) => {
|
||||
// Fetch the data from the store
|
||||
let key = crate::key::thing::new(opt.ns(), opt.db(), &v.tb, &v.id);
|
||||
let val = txn.clone().lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
// Parse the data from the store
|
||||
let val = match val {
|
||||
Some(v) => Value::from(v),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,34 +12,33 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if table has corrent relation status
|
||||
self.relation(ctx, opt, txn, stm).await?;
|
||||
self.relation(ctx, opt, stm).await?;
|
||||
// Alter record data
|
||||
self.alter(stk, ctx, opt, txn, stm).await?;
|
||||
self.alter(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,28 +12,27 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check where clause
|
||||
self.check(stk, ctx, opt, txn, stm).await?;
|
||||
self.check(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Erase document
|
||||
self.erase(ctx, opt, stm).await?;
|
||||
// Purge index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Purge record data
|
||||
self.purge(stk, ctx, opt, txn, stm).await?;
|
||||
self.purge(stk, ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::dbs::Workable;
|
||||
use crate::err::Error;
|
||||
use crate::iam::Action;
|
||||
|
@ -144,13 +144,11 @@ impl<'a> Document<'a> {
|
|||
/// Get the table for this document
|
||||
pub async fn tb(
|
||||
&self,
|
||||
ctx: &Context<'a>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<DefineTableStatement>, Error> {
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the record id
|
||||
let rid = self.id.as_ref().unwrap();
|
||||
// Get the table definition
|
||||
|
@ -177,56 +175,56 @@ impl<'a> Document<'a> {
|
|||
/// Get the foreign tables for this document
|
||||
pub async fn ft(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<[DefineTableStatement]>, Error> {
|
||||
// Get the record id
|
||||
let id = self.id.as_ref().unwrap();
|
||||
// Get the table definitions
|
||||
txn.clone().lock().await.all_tb_views(opt.ns(), opt.db(), &id.tb).await
|
||||
ctx.tx_lock().await.all_tb_views(opt.ns(), opt.db(), &id.tb).await
|
||||
}
|
||||
/// Get the events for this document
|
||||
pub async fn ev(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<[DefineEventStatement]>, Error> {
|
||||
// Get the record id
|
||||
let id = self.id.as_ref().unwrap();
|
||||
// Get the event definitions
|
||||
txn.clone().lock().await.all_tb_events(opt.ns(), opt.db(), &id.tb).await
|
||||
ctx.tx_lock().await.all_tb_events(opt.ns(), opt.db(), &id.tb).await
|
||||
}
|
||||
/// Get the fields for this document
|
||||
pub async fn fd(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<[DefineFieldStatement]>, Error> {
|
||||
// Get the record id
|
||||
let id = self.id.as_ref().unwrap();
|
||||
// Get the field definitions
|
||||
txn.clone().lock().await.all_tb_fields(opt.ns(), opt.db(), &id.tb).await
|
||||
ctx.tx_lock().await.all_tb_fields(opt.ns(), opt.db(), &id.tb).await
|
||||
}
|
||||
/// Get the indexes for this document
|
||||
pub async fn ix(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<[DefineIndexStatement]>, Error> {
|
||||
// Get the record id
|
||||
let id = self.id.as_ref().unwrap();
|
||||
// Get the index definitions
|
||||
txn.clone().lock().await.all_tb_indexes(opt.ns(), opt.db(), &id.tb).await
|
||||
ctx.tx_lock().await.all_tb_indexes(opt.ns(), opt.db(), &id.tb).await
|
||||
}
|
||||
// Get the lives for this document
|
||||
pub async fn lv(
|
||||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Arc<[LiveStatement]>, Error> {
|
||||
// Get the record id
|
||||
let id = self.id.as_ref().unwrap();
|
||||
// Get the table definition
|
||||
txn.clone().lock().await.all_tb_lives(opt.ns(), opt.db(), &id.tb).await
|
||||
ctx.tx_lock().await.all_tb_lives(opt.ns(), opt.db(), &id.tb).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Workable;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::paths::EDGE;
|
||||
|
@ -13,17 +13,16 @@ use crate::sql::Dir;
|
|||
impl<'a> Document<'a> {
|
||||
pub async fn edges(
|
||||
&mut self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if the table is a view
|
||||
if self.tb(opt, txn).await?.drop {
|
||||
if self.tb(ctx, opt).await?.drop {
|
||||
return Ok(());
|
||||
}
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the record id
|
||||
let rid = self.id.as_ref().unwrap();
|
||||
// Store the record edges
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
||||
|
@ -10,7 +9,6 @@ impl<'a> Document<'a> {
|
|||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if this record exists
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -13,7 +13,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check import
|
||||
|
@ -27,7 +26,7 @@ impl<'a> Document<'a> {
|
|||
// Don't run permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
// Loop through all event statements
|
||||
for ev in self.ev(opt, txn).await?.iter() {
|
||||
for ev in self.ev(ctx, opt).await?.iter() {
|
||||
// Get the event action
|
||||
let met = if stm.is_delete() {
|
||||
Value::from("DELETE")
|
||||
|
@ -48,11 +47,11 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", self.current.doc.deref());
|
||||
ctx.add_value("before", self.initial.doc.deref());
|
||||
// Process conditional clause
|
||||
let val = ev.when.compute(stk, &ctx, opt, txn, Some(doc)).await?;
|
||||
let val = ev.when.compute(stk, &ctx, opt, Some(doc)).await?;
|
||||
// Execute event if value is truthy
|
||||
if val.is_truthy() {
|
||||
for v in ev.then.iter() {
|
||||
v.compute(stk, &ctx, opt, txn, Some(doc)).await?;
|
||||
v.compute(stk, &ctx, opt, Some(doc)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::iam::Action;
|
||||
|
@ -14,7 +14,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check import
|
||||
|
@ -26,7 +25,7 @@ impl<'a> Document<'a> {
|
|||
// Get the user applied input
|
||||
let inp = self.initial.doc.changed(self.current.doc.as_ref());
|
||||
// Loop through all field statements
|
||||
for fd in self.fd(opt, txn).await?.iter() {
|
||||
for fd in self.fd(ctx, opt).await?.iter() {
|
||||
// Loop over each field in document
|
||||
for (k, mut val) in self.current.doc.walk(&fd.name).into_iter() {
|
||||
// Get the initial value
|
||||
|
@ -58,7 +57,7 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", &val);
|
||||
ctx.add_value("before", &old);
|
||||
// Process the VALUE clause
|
||||
val = expr.compute(stk, &ctx, opt, txn, Some(&self.current)).await?;
|
||||
val = expr.compute(stk, &ctx, opt, Some(&self.current)).await?;
|
||||
}
|
||||
}
|
||||
// Check for a TYPE clause
|
||||
|
@ -89,7 +88,7 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", &val);
|
||||
ctx.add_value("before", &old);
|
||||
// Process the VALUE clause
|
||||
val = expr.compute(stk, &ctx, opt, txn, Some(&self.current)).await?;
|
||||
val = expr.compute(stk, &ctx, opt, Some(&self.current)).await?;
|
||||
}
|
||||
}
|
||||
// Check for a TYPE clause
|
||||
|
@ -118,7 +117,7 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", &val);
|
||||
ctx.add_value("before", &old);
|
||||
// Process the ASSERT clause
|
||||
if !expr.compute(stk, &ctx, opt, txn, Some(&self.current)).await?.is_truthy() {
|
||||
if !expr.compute(stk, &ctx, opt, Some(&self.current)).await?.is_truthy() {
|
||||
return Err(Error::FieldValue {
|
||||
thing: rid.to_string(),
|
||||
field: fd.name.clone(),
|
||||
|
@ -159,11 +158,7 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", &val);
|
||||
ctx.add_value("before", &old);
|
||||
// Process the PERMISSION clause
|
||||
if !e
|
||||
.compute(stk, &ctx, opt, txn, Some(&self.current))
|
||||
.await?
|
||||
.is_truthy()
|
||||
{
|
||||
if !e.compute(stk, &ctx, opt, Some(&self.current)).await?.is_truthy() {
|
||||
val = old
|
||||
}
|
||||
}
|
||||
|
@ -171,8 +166,8 @@ impl<'a> Document<'a> {
|
|||
}
|
||||
// Set the value of the field
|
||||
match val {
|
||||
Value::None => self.current.doc.to_mut().del(stk, ctx, opt, txn, &k).await?,
|
||||
_ => self.current.doc.to_mut().set(stk, ctx, opt, txn, &k, val).await?,
|
||||
Value::None => self.current.doc.to_mut().del(stk, ctx, opt, &k).await?,
|
||||
_ => self.current.doc.to_mut().set(stk, ctx, opt, &k, val).await?,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::{Force, Statement};
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::{CursorDoc, Document};
|
||||
use crate::err::Error;
|
||||
use crate::idx::ft::FtIndex;
|
||||
|
@ -20,7 +20,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Was this force targeted at a specific index?
|
||||
|
@ -32,12 +31,12 @@ impl<'a> Document<'a> {
|
|||
{
|
||||
ix.clone()
|
||||
}
|
||||
Force::All => self.ix(opt, txn).await?,
|
||||
_ if self.changed() => self.ix(opt, txn).await?,
|
||||
Force::All => self.ix(ctx, opt).await?,
|
||||
_ if self.changed() => self.ix(ctx, opt).await?,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
// Check if the table is a view
|
||||
if self.tb(opt, txn).await?.drop {
|
||||
if self.tb(ctx, opt).await?.drop {
|
||||
return Ok(());
|
||||
}
|
||||
// Get the record id
|
||||
|
@ -45,10 +44,10 @@ impl<'a> Document<'a> {
|
|||
// Loop through all index statements
|
||||
for ix in ixs.iter() {
|
||||
// Calculate old values
|
||||
let o = build_opt_values(stk, ctx, opt, txn, ix, &self.initial).await?;
|
||||
let o = build_opt_values(stk, ctx, opt, ix, &self.initial).await?;
|
||||
|
||||
// Calculate new values
|
||||
let n = build_opt_values(stk, ctx, opt, txn, ix, &self.current).await?;
|
||||
let n = build_opt_values(stk, ctx, opt, ix, &self.current).await?;
|
||||
|
||||
// Update the index entries
|
||||
if targeted_force || o != n {
|
||||
|
@ -57,10 +56,10 @@ impl<'a> Document<'a> {
|
|||
|
||||
// Index operation dispatching
|
||||
match &ix.index {
|
||||
Index::Uniq => ic.index_unique(txn).await?,
|
||||
Index::Idx => ic.index_non_unique(txn).await?,
|
||||
Index::Search(p) => ic.index_full_text(stk, ctx, txn, p).await?,
|
||||
Index::MTree(p) => ic.index_mtree(stk, ctx, txn, p).await?,
|
||||
Index::Uniq => ic.index_unique(ctx).await?,
|
||||
Index::Idx => ic.index_non_unique(ctx).await?,
|
||||
Index::Search(p) => ic.index_full_text(stk, ctx, p).await?,
|
||||
Index::MTree(p) => ic.index_mtree(stk, ctx, p).await?,
|
||||
Index::Hnsw(p) => ic.index_hnsw(ctx, p).await?,
|
||||
};
|
||||
}
|
||||
|
@ -78,7 +77,6 @@ async fn build_opt_values(
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
ix: &DefineIndexStatement,
|
||||
doc: &CursorDoc<'_>,
|
||||
) -> Result<Option<Vec<Value>>, Error> {
|
||||
|
@ -87,7 +85,7 @@ async fn build_opt_values(
|
|||
}
|
||||
let mut o = Vec::with_capacity(ix.cols.len());
|
||||
for i in ix.cols.iter() {
|
||||
let v = i.compute(stk, ctx, opt, txn, Some(doc)).await?;
|
||||
let v = i.compute(stk, ctx, opt, Some(doc)).await?;
|
||||
o.push(v);
|
||||
}
|
||||
Ok(Some(o))
|
||||
|
@ -281,8 +279,8 @@ impl<'a> IndexOperation<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
async fn index_unique(&mut self, txn: &Transaction) -> Result<(), Error> {
|
||||
let mut run = txn.lock().await;
|
||||
async fn index_unique(&mut self, ctx: &Context<'_>) -> Result<(), Error> {
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Delete the old index data
|
||||
if let Some(o) = self.o.take() {
|
||||
let i = Indexable::new(o, self.ix);
|
||||
|
@ -313,8 +311,8 @@ impl<'a> IndexOperation<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn index_non_unique(&mut self, txn: &Transaction) -> Result<(), Error> {
|
||||
let mut run = txn.lock().await;
|
||||
async fn index_non_unique(&mut self, ctx: &Context<'_>) -> Result<(), Error> {
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Delete the old index data
|
||||
if let Some(o) = self.o.take() {
|
||||
let i = Indexable::new(o, self.ix);
|
||||
|
@ -358,38 +356,27 @@ impl<'a> IndexOperation<'a> {
|
|||
&mut self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
txn: &Transaction,
|
||||
p: &SearchParams,
|
||||
) -> Result<(), Error> {
|
||||
let ikb = IndexKeyBase::new(self.opt, self.ix);
|
||||
|
||||
let mut ft = FtIndex::new(
|
||||
ctx.get_index_stores(),
|
||||
self.opt,
|
||||
txn,
|
||||
&p.az,
|
||||
ikb,
|
||||
p,
|
||||
TransactionType::Write,
|
||||
)
|
||||
.await?;
|
||||
let mut ft = FtIndex::new(ctx, self.opt, &p.az, ikb, p, TransactionType::Write).await?;
|
||||
|
||||
if let Some(n) = self.n.take() {
|
||||
ft.index_document(stk, ctx, self.opt, txn, self.rid, n).await?;
|
||||
ft.index_document(stk, ctx, self.opt, self.rid, n).await?;
|
||||
} else {
|
||||
ft.remove_document(txn, self.rid).await?;
|
||||
ft.remove_document(ctx, self.rid).await?;
|
||||
}
|
||||
ft.finish(txn).await
|
||||
ft.finish(ctx).await
|
||||
}
|
||||
|
||||
async fn index_mtree(
|
||||
&mut self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
txn: &Transaction,
|
||||
p: &MTreeParams,
|
||||
) -> Result<(), Error> {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let ikb = IndexKeyBase::new(self.opt, self.ix);
|
||||
let mut mt =
|
||||
MTreeIndex::new(ctx.get_index_stores(), &mut tx, ikb, p, TransactionType::Write)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,7 +12,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check whether current record exists
|
||||
|
@ -20,13 +19,13 @@ impl<'a> Document<'a> {
|
|||
// We attempted to INSERT a document with an ID,
|
||||
// and this ID already exists in the database,
|
||||
// so we need to update the record instead.
|
||||
true => self.insert_update(stk, ctx, opt, txn, stm).await,
|
||||
true => self.insert_update(stk, ctx, opt, stm).await,
|
||||
// We attempted to INSERT a document with an ID,
|
||||
// which does not exist in the database, or we
|
||||
// are creating a new record with a new ID.
|
||||
false => {
|
||||
// First of all let's try to create the record
|
||||
match self.insert_create(stk, ctx, opt, txn, stm).await {
|
||||
match self.insert_create(stk, ctx, opt, stm).await {
|
||||
// We received an index exists error, so we
|
||||
// ignore the error, and attempt to update the
|
||||
// record using the ON DUPLICATE KEY clause
|
||||
|
@ -50,35 +49,34 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if table has correct relation status
|
||||
self.relation(ctx, opt, txn, stm).await?;
|
||||
self.relation(ctx, opt, stm).await?;
|
||||
// Merge record data
|
||||
self.merge(stk, ctx, opt, txn, stm).await?;
|
||||
self.merge(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
// Attempt to run an UPDATE clause
|
||||
async fn insert_update(
|
||||
|
@ -86,34 +84,33 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Alter record data
|
||||
self.alter(stk, ctx, opt, txn, stm).await?;
|
||||
self.alter(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Action;
|
||||
use crate::dbs::Notification;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Action, Transaction};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
@ -24,9 +24,8 @@ impl<'a> Document<'a> {
|
|||
pub async fn lives(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if changed
|
||||
|
@ -41,10 +40,9 @@ impl<'a> Document<'a> {
|
|||
// Check if we can send notifications
|
||||
if let Some(chn) = &opt.sender {
|
||||
// Loop through all index statements
|
||||
let lq_stms = self.lv(opt, txn).await?;
|
||||
let lq_stms = self.lv(ctx, opt).await?;
|
||||
let borrows = lq_stms.iter().collect::<Vec<_>>();
|
||||
self.check_lqs_and_send_notifications(stk, opt, stm, txn, borrows.as_slice(), chn)
|
||||
.await?;
|
||||
self.check_lqs_and_send_notifications(stk, opt, stm, borrows.as_slice(), chn).await?;
|
||||
}
|
||||
// Carry on
|
||||
Ok(())
|
||||
|
@ -56,14 +54,13 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
doc: &CursorDoc<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check where condition
|
||||
if let Some(cond) = stm.conds() {
|
||||
// Check if the expression is truthy
|
||||
if !cond.compute(stk, ctx, opt, txn, Some(doc)).await?.is_truthy() {
|
||||
if !cond.compute(stk, ctx, opt, Some(doc)).await?.is_truthy() {
|
||||
// Ignore this document
|
||||
return Err(Error::Ignore);
|
||||
}
|
||||
|
@ -78,14 +75,13 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
doc: &CursorDoc<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Should we run permissions checks?
|
||||
if opt.check_perms(stm.into()) {
|
||||
// Get the table
|
||||
let tb = self.tb(opt, txn).await?;
|
||||
let tb = self.tb(ctx, opt).await?;
|
||||
// Process the table permissions
|
||||
match &tb.permissions.select {
|
||||
Permission::None => return Err(Error::Ignore),
|
||||
|
@ -94,7 +90,7 @@ impl<'a> Document<'a> {
|
|||
// Disable permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
// Process the PERMISSION clause
|
||||
if !e.compute(stk, ctx, opt, txn, Some(doc)).await?.is_truthy() {
|
||||
if !e.compute(stk, ctx, opt, Some(doc)).await?.is_truthy() {
|
||||
return Err(Error::Ignore);
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +106,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
opt: &Options,
|
||||
stm: &Statement<'_>,
|
||||
txn: &Transaction,
|
||||
live_statements: &[&LiveStatement],
|
||||
sender: &Sender<Notification>,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -180,7 +175,7 @@ impl<'a> Document<'a> {
|
|||
// First of all, let's check to see if the WHERE
|
||||
// clause of the LIVE query is matched by this
|
||||
// document. If it is then we can continue.
|
||||
match self.lq_check(stk, &lqctx, &lqopt, txn, &lq, doc).await {
|
||||
match self.lq_check(stk, &lqctx, &lqopt, &lq, doc).await {
|
||||
Err(Error::Ignore) => {
|
||||
trace!("live query did not match the where clause, skipping");
|
||||
continue;
|
||||
|
@ -192,7 +187,7 @@ impl<'a> Document<'a> {
|
|||
// clause for this table allows this document to
|
||||
// be viewed by the user who created this LIVE
|
||||
// query. If it does, then we can continue.
|
||||
match self.lq_allow(stk, &lqctx, &lqopt, txn, &lq, doc).await {
|
||||
match self.lq_allow(stk, &lqctx, &lqopt, &lq, doc).await {
|
||||
Err(Error::Ignore) => {
|
||||
trace!("live query did not have permission to view this document, skipping");
|
||||
continue;
|
||||
|
@ -228,14 +223,14 @@ impl<'a> Document<'a> {
|
|||
let lqopt: &Options = &lqopt.new_with_futures(true);
|
||||
// Output the full document before any changes were applied
|
||||
let mut value =
|
||||
doc.doc.compute(stk, &lqctx, lqopt, txn, Some(doc)).await?;
|
||||
doc.doc.compute(stk, &lqctx, lqopt, Some(doc)).await?;
|
||||
|
||||
// TODO(SUR-349): We need an empty object instead of Value::None for serialisation
|
||||
if value.is_none() {
|
||||
value = Value::Object(Default::default());
|
||||
}
|
||||
// Remove metadata fields on output
|
||||
value.del(stk, &lqctx, lqopt, txn, &*META).await?;
|
||||
value.del(stk, &lqctx, lqopt, &*META).await?;
|
||||
// Output result
|
||||
value
|
||||
},
|
||||
|
@ -250,7 +245,7 @@ impl<'a> Document<'a> {
|
|||
.send(Notification {
|
||||
id: lv.id,
|
||||
action: Action::Create,
|
||||
result: self.pluck(stk, &lqctx, &lqopt, txn, &lq).await?,
|
||||
result: self.pluck(stk, &lqctx, &lqopt, &lq).await?,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
|
@ -262,7 +257,7 @@ impl<'a> Document<'a> {
|
|||
.send(Notification {
|
||||
id: lv.id,
|
||||
action: Action::Update,
|
||||
result: self.pluck(stk, &lqctx, &lqopt, txn, &lq).await?,
|
||||
result: self.pluck(stk, &lqctx, &lqopt, &lq).await?,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Workable;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use reblessive::tree::Stk;
|
||||
|
@ -12,7 +12,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the record id
|
||||
|
@ -21,7 +20,7 @@ impl<'a> Document<'a> {
|
|||
self.current.doc.to_mut().def(rid);
|
||||
// This is an INSERT statement
|
||||
if let Workable::Insert(v) = &self.extras {
|
||||
let v = v.compute(stk, ctx, opt, txn, Some(&self.current)).await?;
|
||||
let v = v.compute(stk, ctx, opt, Some(&self.current)).await?;
|
||||
self.current.doc.to_mut().merge(v)?;
|
||||
}
|
||||
// Set default field values
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::iam::Action;
|
||||
|
@ -20,7 +20,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Ensure futures are run
|
||||
|
@ -36,11 +35,11 @@ impl<'a> Document<'a> {
|
|||
}
|
||||
Output::After => {
|
||||
// Output the full document after all changes were applied
|
||||
self.current.doc.compute(stk, ctx, opt, txn, Some(&self.current)).await
|
||||
self.current.doc.compute(stk, ctx, opt, Some(&self.current)).await
|
||||
}
|
||||
Output::Before => {
|
||||
// Output the full document before any changes were applied
|
||||
self.initial.doc.compute(stk, ctx, opt, txn, Some(&self.initial)).await
|
||||
self.initial.doc.compute(stk, ctx, opt, Some(&self.initial)).await
|
||||
}
|
||||
Output::Fields(v) => {
|
||||
// Configure the context
|
||||
|
@ -48,28 +47,28 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("after", self.current.doc.as_ref());
|
||||
ctx.add_value("before", self.initial.doc.as_ref());
|
||||
// Output the specified fields
|
||||
v.compute(stk, &ctx, opt, txn, Some(&self.current), false).await
|
||||
v.compute(stk, &ctx, opt, Some(&self.current), false).await
|
||||
}
|
||||
},
|
||||
None => match stm {
|
||||
Statement::Live(s) => match s.expr.len() {
|
||||
0 => Ok(self.initial.doc.diff(&self.current.doc, Idiom::default()).into()),
|
||||
_ => s.expr.compute(stk, ctx, opt, txn, Some(&self.current), false).await,
|
||||
_ => s.expr.compute(stk, ctx, opt, Some(&self.current), false).await,
|
||||
},
|
||||
Statement::Select(s) => {
|
||||
s.expr.compute(stk, ctx, opt, txn, Some(&self.current), s.group.is_some()).await
|
||||
s.expr.compute(stk, ctx, opt, Some(&self.current), s.group.is_some()).await
|
||||
}
|
||||
Statement::Create(_) => {
|
||||
self.current.doc.compute(stk, ctx, opt, txn, Some(&self.current)).await
|
||||
self.current.doc.compute(stk, ctx, opt, Some(&self.current)).await
|
||||
}
|
||||
Statement::Update(_) => {
|
||||
self.current.doc.compute(stk, ctx, opt, txn, Some(&self.current)).await
|
||||
self.current.doc.compute(stk, ctx, opt, Some(&self.current)).await
|
||||
}
|
||||
Statement::Relate(_) => {
|
||||
self.current.doc.compute(stk, ctx, opt, txn, Some(&self.current)).await
|
||||
self.current.doc.compute(stk, ctx, opt, Some(&self.current)).await
|
||||
}
|
||||
Statement::Insert(_) => {
|
||||
self.current.doc.compute(stk, ctx, opt, txn, Some(&self.current)).await
|
||||
self.current.doc.compute(stk, ctx, opt, Some(&self.current)).await
|
||||
}
|
||||
_ => Err(Error::Ignore),
|
||||
},
|
||||
|
@ -79,13 +78,13 @@ impl<'a> Document<'a> {
|
|||
// Should we run permissions checks?
|
||||
if opt.check_perms(Action::View) {
|
||||
// Loop through all field statements
|
||||
for fd in self.fd(opt, txn).await?.iter() {
|
||||
for fd in self.fd(ctx, opt).await?.iter() {
|
||||
// Loop over each field in document
|
||||
for k in out.each(&fd.name).iter() {
|
||||
// Process the field permissions
|
||||
match &fd.permissions.select {
|
||||
Permission::Full => (),
|
||||
Permission::None => out.del(stk, ctx, opt, txn, k).await?,
|
||||
Permission::None => out.del(stk, ctx, opt, k).await?,
|
||||
Permission::Specific(e) => {
|
||||
// Disable permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
|
@ -96,11 +95,11 @@ impl<'a> Document<'a> {
|
|||
ctx.add_value("value", &val);
|
||||
// Process the PERMISSION clause
|
||||
if !e
|
||||
.compute(stk, &ctx, opt, txn, Some(&self.current))
|
||||
.compute(stk, &ctx, opt, Some(&self.current))
|
||||
.await?
|
||||
.is_truthy()
|
||||
{
|
||||
out.del(stk, &ctx, opt, txn, k).await?
|
||||
out.del(stk, &ctx, opt, k).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ impl<'a> Document<'a> {
|
|||
// Remove any omitted fields from output
|
||||
if let Some(v) = stm.omit() {
|
||||
for v in v.iter() {
|
||||
out.del(stk, ctx, opt, txn, v).await?;
|
||||
out.del(stk, ctx, opt, v).await?;
|
||||
}
|
||||
}
|
||||
// Remove metadata fields on output
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Operable;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Workable;
|
||||
use crate::dbs::{Operable, Transaction};
|
||||
use crate::dbs::{Options, Processed};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
@ -14,7 +14,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
mut pro: Processed,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -30,12 +29,12 @@ impl<'a> Document<'a> {
|
|||
let mut doc = Document::new(pro.rid.as_ref(), pro.ir.as_ref(), &ins.0, ins.1);
|
||||
// Process the statement
|
||||
let res = match stm {
|
||||
Statement::Select(_) => doc.select(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Update(_) => doc.update(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Create(_) => doc.create(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Relate(_) => doc.relate(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Delete(_) => doc.delete(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Insert(_) => doc.insert(stk, ctx, opt, txn, stm).await,
|
||||
Statement::Select(_) => doc.select(stk, ctx, opt, stm).await,
|
||||
Statement::Update(_) => doc.update(stk, ctx, opt, stm).await,
|
||||
Statement::Create(_) => doc.create(stk, ctx, opt, stm).await,
|
||||
Statement::Relate(_) => doc.relate(stk, ctx, opt, stm).await,
|
||||
Statement::Delete(_) => doc.delete(stk, ctx, opt, stm).await,
|
||||
Statement::Insert(_) => doc.insert(stk, ctx, opt, stm).await,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Check the result
|
||||
|
@ -46,7 +45,7 @@ impl<'a> Document<'a> {
|
|||
Err(Error::RetryWithId(v)) => {
|
||||
// Fetch the data from the store
|
||||
let key = crate::key::thing::new(opt.ns(), opt.db(), &v.tb, &v.id);
|
||||
let val = txn.clone().lock().await.get(key).await?;
|
||||
let val = ctx.tx_lock().await.get(key).await?;
|
||||
// Parse the data from the store
|
||||
let val = match val {
|
||||
Some(v) => Value::from(v),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::dir::Dir;
|
||||
|
@ -19,17 +19,14 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if changed
|
||||
if !self.changed() {
|
||||
return Ok(());
|
||||
}
|
||||
// Clone transaction
|
||||
let run = txn.clone();
|
||||
// Claim transaction
|
||||
let mut run = run.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the record id
|
||||
if let Some(rid) = self.id {
|
||||
// Purge the record data
|
||||
|
@ -70,7 +67,7 @@ impl<'a> Document<'a> {
|
|||
..DeleteStatement::default()
|
||||
};
|
||||
// Execute the delete statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,72 +12,71 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if table has correct relation status
|
||||
self.relation(ctx, opt, txn, stm).await?;
|
||||
self.relation(ctx, opt, stm).await?;
|
||||
// Check current record
|
||||
match self.current.doc.is_some() {
|
||||
// Create new edge
|
||||
false => {
|
||||
// Store record edges
|
||||
self.edges(ctx, opt, txn, stm).await?;
|
||||
self.edges(ctx, opt, stm).await?;
|
||||
// Alter record data
|
||||
self.alter(stk, ctx, opt, txn, stm).await?;
|
||||
self.alter(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
// Update old edge
|
||||
true => {
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store record edges
|
||||
self.edges(ctx, opt, txn, stm).await?;
|
||||
self.edges(ctx, opt, stm).await?;
|
||||
// Alter record data
|
||||
self.alter(stk, ctx, opt, txn, stm).await?;
|
||||
self.alter(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
||||
impl<'a> Document<'a> {
|
||||
pub async fn relation(
|
||||
&mut self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
let tb = self.tb(opt, txn).await?;
|
||||
let tb = self.tb(ctx, opt).await?;
|
||||
|
||||
let rid = self.id.as_ref().unwrap();
|
||||
match stm {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::dbs::Workable;
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
|
@ -15,7 +14,6 @@ impl<'a> Document<'a> {
|
|||
&mut self,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Get the record id
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,16 +12,15 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if record exists
|
||||
self.empty(ctx, opt, txn, stm).await?;
|
||||
self.empty(ctx, opt, stm).await?;
|
||||
// Check where clause
|
||||
self.check(stk, ctx, opt, txn, stm).await?;
|
||||
self.check(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::key::key_req::KeyRequirements;
|
||||
|
@ -8,9 +8,8 @@ use crate::key::key_req::KeyRequirements;
|
|||
impl<'a> Document<'a> {
|
||||
pub async fn store(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check if changed
|
||||
|
@ -18,11 +17,11 @@ impl<'a> Document<'a> {
|
|||
return Ok(());
|
||||
}
|
||||
// Check if the table is a view
|
||||
if self.tb(opt, txn).await?.drop {
|
||||
if self.tb(ctx, opt).await?.drop {
|
||||
return Ok(());
|
||||
}
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the record id
|
||||
let rid = self.id.as_ref().unwrap();
|
||||
// Store the record data
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::{Force, Statement};
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::data::Data;
|
||||
|
@ -36,7 +36,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<(), Error> {
|
||||
// Check import
|
||||
|
@ -56,8 +55,8 @@ impl<'a> Document<'a> {
|
|||
{
|
||||
tb.clone()
|
||||
}
|
||||
Force::All => self.ft(opt, txn).await?,
|
||||
_ if self.changed() => self.ft(opt, txn).await?,
|
||||
Force::All => self.ft(ctx, opt).await?,
|
||||
_ if self.changed() => self.ft(ctx, opt).await?,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
// Don't run permissions
|
||||
|
@ -83,7 +82,7 @@ impl<'a> Document<'a> {
|
|||
let id = stk
|
||||
.scope(|scope| {
|
||||
try_join_all(group.iter().map(|v| {
|
||||
scope.run(|stk| v.compute(stk, ctx, opt, txn, Some(&self.initial)))
|
||||
scope.run(|stk| v.compute(stk, ctx, opt, Some(&self.initial)))
|
||||
}))
|
||||
})
|
||||
.await?
|
||||
|
@ -99,7 +98,7 @@ impl<'a> Document<'a> {
|
|||
let id = stk
|
||||
.scope(|scope| {
|
||||
try_join_all(group.iter().map(|v| {
|
||||
scope.run(|stk| v.compute(stk, ctx, opt, txn, Some(&self.current)))
|
||||
scope.run(|stk| v.compute(stk, ctx, opt, Some(&self.current)))
|
||||
}))
|
||||
})
|
||||
.await?
|
||||
|
@ -115,7 +114,7 @@ impl<'a> Document<'a> {
|
|||
match &tb.cond {
|
||||
// There is a WHERE clause specified
|
||||
Some(cond) => {
|
||||
match cond.compute(stk, ctx, opt, txn, Some(&self.current)).await? {
|
||||
match cond.compute(stk, ctx, opt, Some(&self.current)).await? {
|
||||
v if v.is_truthy() => {
|
||||
if !targeted_force && act != Action::Create {
|
||||
// Delete the old value
|
||||
|
@ -124,13 +123,12 @@ impl<'a> Document<'a> {
|
|||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::from(old)]),
|
||||
data: Some(
|
||||
self.data(stk, ctx, opt, txn, act, &tb.expr)
|
||||
.await?,
|
||||
self.data(stk, ctx, opt, act, &tb.expr).await?,
|
||||
),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
if act != Action::Delete {
|
||||
// Update the new value
|
||||
|
@ -139,13 +137,12 @@ impl<'a> Document<'a> {
|
|||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::from(rid)]),
|
||||
data: Some(
|
||||
self.data(stk, ctx, opt, txn, act, &tb.expr)
|
||||
.await?,
|
||||
self.data(stk, ctx, opt, act, &tb.expr).await?,
|
||||
),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -156,13 +153,12 @@ impl<'a> Document<'a> {
|
|||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::from(old)]),
|
||||
data: Some(
|
||||
self.data(stk, ctx, opt, txn, act, &tb.expr)
|
||||
.await?,
|
||||
self.data(stk, ctx, opt, act, &tb.expr).await?,
|
||||
),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,11 +171,11 @@ impl<'a> Document<'a> {
|
|||
// Modify the value in the table
|
||||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::from(old)]),
|
||||
data: Some(self.data(stk, ctx, opt, txn, act, &tb.expr).await?),
|
||||
data: Some(self.data(stk, ctx, opt, act, &tb.expr).await?),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
if act != Action::Delete {
|
||||
// Update the new value
|
||||
|
@ -187,11 +183,11 @@ impl<'a> Document<'a> {
|
|||
// Modify the value in the table
|
||||
let stm = UpdateStatement {
|
||||
what: Values(vec![Value::from(rid)]),
|
||||
data: Some(self.data(stk, ctx, opt, txn, act, &tb.expr).await?),
|
||||
data: Some(self.data(stk, ctx, opt, act, &tb.expr).await?),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +203,7 @@ impl<'a> Document<'a> {
|
|||
match &tb.cond {
|
||||
// There is a WHERE clause specified
|
||||
Some(cond) => {
|
||||
match cond.compute(stk, ctx, opt, txn, Some(&self.current)).await? {
|
||||
match cond.compute(stk, ctx, opt, Some(&self.current)).await? {
|
||||
v if v.is_truthy() => {
|
||||
// Define the statement
|
||||
let stm = match act {
|
||||
|
@ -219,14 +215,12 @@ impl<'a> Document<'a> {
|
|||
// Update the value in the table
|
||||
_ => Query::Update(UpdateStatement {
|
||||
what: Values(vec![Value::from(rid)]),
|
||||
data: Some(
|
||||
self.full(stk, ctx, opt, txn, &tb.expr).await?,
|
||||
),
|
||||
data: Some(self.full(stk, ctx, opt, &tb.expr).await?),
|
||||
..UpdateStatement::default()
|
||||
}),
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
_ => {
|
||||
// Delete the value in the table
|
||||
|
@ -235,7 +229,7 @@ impl<'a> Document<'a> {
|
|||
..DeleteStatement::default()
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,12 +245,12 @@ impl<'a> Document<'a> {
|
|||
// Update the value in the table
|
||||
_ => Query::Update(UpdateStatement {
|
||||
what: Values(vec![Value::from(rid)]),
|
||||
data: Some(self.full(stk, ctx, opt, txn, &tb.expr).await?),
|
||||
data: Some(self.full(stk, ctx, opt, &tb.expr).await?),
|
||||
..UpdateStatement::default()
|
||||
}),
|
||||
};
|
||||
// Execute the statement
|
||||
stm.compute(stk, ctx, opt, txn, None).await?;
|
||||
stm.compute(stk, ctx, opt, None).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,10 +265,9 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
exp: &Fields,
|
||||
) -> Result<Data, Error> {
|
||||
let mut data = exp.compute(stk, ctx, opt, txn, Some(&self.current), false).await?;
|
||||
let mut data = exp.compute(stk, ctx, opt, Some(&self.current), false).await?;
|
||||
data.cut(ID.as_ref());
|
||||
Ok(Data::ReplaceExpression(data))
|
||||
}
|
||||
|
@ -284,7 +277,6 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
act: Action,
|
||||
exp: &Fields,
|
||||
) -> Result<Data, Error> {
|
||||
|
@ -314,29 +306,29 @@ impl<'a> Document<'a> {
|
|||
match expr {
|
||||
Value::Function(f) if f.is_rolling() => match f.name() {
|
||||
Some("count") => {
|
||||
let val = f.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = f.compute(stk, ctx, opt, doc).await?;
|
||||
self.chg(&mut ops, &act, idiom, val);
|
||||
}
|
||||
Some("math::sum") => {
|
||||
let val = f.args()[0].compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = f.args()[0].compute(stk, ctx, opt, doc).await?;
|
||||
self.chg(&mut ops, &act, idiom, val);
|
||||
}
|
||||
Some("math::min") | Some("time::min") => {
|
||||
let val = f.args()[0].compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = f.args()[0].compute(stk, ctx, opt, doc).await?;
|
||||
self.min(&mut ops, &act, idiom, val);
|
||||
}
|
||||
Some("math::max") | Some("time::max") => {
|
||||
let val = f.args()[0].compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = f.args()[0].compute(stk, ctx, opt, doc).await?;
|
||||
self.max(&mut ops, &act, idiom, val);
|
||||
}
|
||||
Some("math::mean") => {
|
||||
let val = f.args()[0].compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = f.args()[0].compute(stk, ctx, opt, doc).await?;
|
||||
self.mean(&mut ops, &act, idiom, val);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
_ => {
|
||||
let val = expr.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let val = expr.compute(stk, ctx, opt, doc).await?;
|
||||
self.set(&mut ops, idiom, val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Statement;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::doc::Document;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -12,36 +12,35 @@ impl<'a> Document<'a> {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stm: &Statement<'_>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check where clause
|
||||
self.check(stk, ctx, opt, txn, stm).await?;
|
||||
self.check(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Alter record data
|
||||
self.alter(stk, ctx, opt, txn, stm).await?;
|
||||
self.alter(stk, ctx, opt, stm).await?;
|
||||
// Merge fields data
|
||||
self.field(stk, ctx, opt, txn, stm).await?;
|
||||
self.field(stk, ctx, opt, stm).await?;
|
||||
// Reset fields data
|
||||
self.reset(ctx, opt, txn, stm).await?;
|
||||
self.reset(ctx, opt, stm).await?;
|
||||
// Clean fields data
|
||||
self.clean(stk, ctx, opt, txn, stm).await?;
|
||||
self.clean(stk, ctx, opt, stm).await?;
|
||||
// Check if allowed
|
||||
self.allow(stk, ctx, opt, txn, stm).await?;
|
||||
self.allow(stk, ctx, opt, stm).await?;
|
||||
// Store record data
|
||||
self.store(ctx, opt, txn, stm).await?;
|
||||
self.store(ctx, opt, stm).await?;
|
||||
// Store index data
|
||||
self.index(stk, ctx, opt, txn, stm).await?;
|
||||
self.index(stk, ctx, opt, stm).await?;
|
||||
// Run table queries
|
||||
self.table(stk, ctx, opt, txn, stm).await?;
|
||||
self.table(stk, ctx, opt, stm).await?;
|
||||
// Run lives queries
|
||||
self.lives(stk, ctx, opt, txn, stm).await?;
|
||||
self.lives(stk, ctx, opt, stm).await?;
|
||||
// Run change feeds queries
|
||||
self.changefeeds(ctx, opt, txn, stm).await?;
|
||||
self.changefeeds(ctx, opt, stm).await?;
|
||||
// Run event queries
|
||||
self.event(stk, ctx, opt, txn, stm).await?;
|
||||
self.event(stk, ctx, opt, stm).await?;
|
||||
// Yield document
|
||||
self.pluck(stk, ctx, opt, txn, stm).await
|
||||
self.pluck(stk, ctx, opt, stm).await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//! Executes functions from SQL. If there is an SQL function it will be defined in this module.
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::executor::QueryExecutor;
|
||||
|
@ -40,7 +39,6 @@ pub async fn run(
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
name: &str,
|
||||
args: Vec<Value>,
|
||||
|
@ -55,7 +53,7 @@ pub async fn run(
|
|||
|| name.starts_with("crypto::pbkdf2")
|
||||
|| name.starts_with("crypto::scrypt")
|
||||
{
|
||||
stk.run(|stk| asynchronous(stk, ctx, Some(opt), Some(txn), doc, name, args)).await
|
||||
stk.run(|stk| asynchronous(stk, ctx, Some(opt), doc, name, args)).await
|
||||
} else {
|
||||
synchronous(ctx, doc, name, args)
|
||||
}
|
||||
|
@ -385,7 +383,6 @@ pub async fn asynchronous(
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: Option<&Options>,
|
||||
txn: Option<&Transaction>,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
name: &str,
|
||||
args: Vec<Value>,
|
||||
|
@ -425,15 +422,15 @@ pub async fn asynchronous(
|
|||
"http::patch" => http::patch(ctx).await,
|
||||
"http::delete" => http::delete(ctx).await,
|
||||
//
|
||||
"search::analyze" => search::analyze((stk,ctx, txn, opt)).await,
|
||||
"search::score" => search::score((ctx, txn, doc)).await,
|
||||
"search::highlight" => search::highlight((ctx,txn, doc)).await,
|
||||
"search::offsets" => search::offsets((ctx, txn, doc)).await,
|
||||
"search::analyze" => search::analyze((stk,ctx, opt)).await,
|
||||
"search::score" => search::score((ctx, doc)).await,
|
||||
"search::highlight" => search::highlight((ctx, doc)).await,
|
||||
"search::offsets" => search::offsets((ctx, doc)).await,
|
||||
//
|
||||
"sleep" => sleep::sleep(ctx).await,
|
||||
//
|
||||
"type::field" => r#type::field((stk,ctx, opt, txn, doc)).await,
|
||||
"type::fields" => r#type::fields((stk,ctx, opt, txn, doc)).await,
|
||||
"type::field" => r#type::field((stk,ctx, opt, doc)).await,
|
||||
"type::fields" => r#type::fields((stk,ctx, opt, doc)).await,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::executor::QueryExecutor;
|
||||
|
@ -211,12 +211,10 @@ fn get_executor_option<'a>(
|
|||
ExecutorOption::None
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn matches(
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
exp: &Expression,
|
||||
l: Value,
|
||||
|
@ -225,9 +223,7 @@ pub(crate) async fn matches(
|
|||
let res = match get_executor_option(ctx, doc, exp) {
|
||||
ExecutorOption::PreMatch => true,
|
||||
ExecutorOption::None => false,
|
||||
ExecutorOption::Execute(exe, thg) => {
|
||||
exe.matches(stk, ctx, opt, txn, thg, exp, l, r).await?
|
||||
}
|
||||
ExecutorOption::Execute(exe, thg) => exe.matches(stk, ctx, opt, thg, exp, l, r).await?,
|
||||
};
|
||||
Ok(res.into())
|
||||
}
|
||||
|
@ -236,14 +232,13 @@ pub(crate) async fn knn(
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
exp: &Expression,
|
||||
) -> Result<Value, Error> {
|
||||
match get_executor_option(ctx, doc, exp) {
|
||||
ExecutorOption::PreMatch => Ok(Value::Bool(true)),
|
||||
ExecutorOption::None => Ok(Value::Bool(false)),
|
||||
ExecutorOption::Execute(exe, thg) => exe.knn(stk, ctx, opt, txn, thg, doc, exp).await,
|
||||
ExecutorOption::Execute(exe, thg) => exe.knn(stk, ctx, opt, thg, doc, exp).await,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use super::modules::resolver;
|
|||
use super::modules::surrealdb::query::QueryContext;
|
||||
use super::modules::surrealdb::query::QUERY_DATA_PROP_NAME;
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -24,7 +24,6 @@ use js::{Class, Ctx, Function, Module, Promise};
|
|||
pub unsafe fn create_query_data<'a>(
|
||||
context: &'a Context<'a>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
doc: Option<&'a CursorDoc<'a>>,
|
||||
ctx: &Ctx<'_>,
|
||||
) -> Result<(), js::Error> {
|
||||
|
@ -36,7 +35,6 @@ pub unsafe fn create_query_data<'a>(
|
|||
QueryContext {
|
||||
context,
|
||||
opt,
|
||||
txn,
|
||||
doc,
|
||||
},
|
||||
)?;
|
||||
|
@ -51,7 +49,6 @@ pub unsafe fn create_query_data<'a>(
|
|||
pub async fn run(
|
||||
context: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
src: &str,
|
||||
arg: Vec<Value>,
|
||||
|
@ -88,7 +85,7 @@ pub async fn run(
|
|||
|
||||
// SAFETY: This is safe because the runtime only lives for the duration of this
|
||||
// function. For the entire duration of which context, opt, txn and doc are valid.
|
||||
unsafe{ create_query_data(context,opt,txn,doc,&ctx) }?;
|
||||
unsafe{ create_query_data(context,opt,doc,&ctx) }?;
|
||||
// Register the surrealdb module as a global object
|
||||
let (module,promise) = Module::evaluate_def::<modules::surrealdb::Package, _>(ctx.clone(), "surrealdb")?;
|
||||
promise.finish::<()>()?;
|
||||
|
|
|
@ -73,7 +73,7 @@ async fn fut(js_ctx: js::Ctx<'_>, name: &str, args: Vec<Value>) -> Result<Value>
|
|||
let this = js_ctx.globals().get::<_, OwnedBorrow<QueryContext>>(QUERY_DATA_PROP_NAME)?;
|
||||
// Process the called function
|
||||
let res = Stk::enter_run(|stk| {
|
||||
fnc::asynchronous(stk, this.context, Some(this.opt), Some(this.txn), this.doc, name, args)
|
||||
fnc::asynchronous(stk, this.context, Some(this.opt), this.doc, name, args)
|
||||
})
|
||||
.await;
|
||||
// Convert any response error
|
||||
|
|
|
@ -19,7 +19,7 @@ async fn value(ctx: Ctx<'_>, value: Coerced<String>) -> Result<SurValue> {
|
|||
let this = ctx.globals().get::<_, OwnedBorrow<QueryContext>>(QUERY_DATA_PROP_NAME)?;
|
||||
let value = Stk::enter_run(|stk| async {
|
||||
value
|
||||
.compute(stk, this.context, this.opt, this.txn, this.doc)
|
||||
.compute(stk, this.context, this.opt, this.doc)
|
||||
.await
|
||||
.map_err(|e| Exception::throw_message(&ctx, &e.to_string()))
|
||||
})
|
||||
|
|
|
@ -7,7 +7,7 @@ use reblessive::tree::Stk;
|
|||
|
||||
use crate::{
|
||||
ctx::Context,
|
||||
dbs::{Attach, Options, Transaction},
|
||||
dbs::{Attach, Options},
|
||||
doc::CursorDoc,
|
||||
sql::Value as SurValue,
|
||||
};
|
||||
|
@ -24,7 +24,6 @@ pub const QUERY_DATA_PROP_NAME: &str = "__query_context__";
|
|||
pub struct QueryContext<'js> {
|
||||
pub context: &'js Context<'js>,
|
||||
pub opt: &'js Options,
|
||||
pub txn: &'js Transaction,
|
||||
pub doc: Option<&'js CursorDoc<'js>>,
|
||||
}
|
||||
|
||||
|
@ -78,9 +77,8 @@ pub async fn query<'js>(
|
|||
.attach(context)
|
||||
.map_err(|e| Exception::throw_message(&ctx, &e.to_string()))?;
|
||||
|
||||
let value =
|
||||
Stk::enter_run(|stk| query.query.compute(stk, &context, this.opt, this.txn, this.doc))
|
||||
.await
|
||||
.map_err(|e| Exception::throw_message(&ctx, &e.to_string()))?;
|
||||
let value = Stk::enter_run(|stk| query.query.compute(stk, &context, this.opt, this.doc))
|
||||
.await
|
||||
.map_err(|e| Exception::throw_message(&ctx, &e.to_string()))?;
|
||||
Result::Ok(value)
|
||||
}
|
||||
|
|
|
@ -1,61 +1,54 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::fnc::get_execution_context;
|
||||
use crate::idx::ft::analyzer::Analyzer;
|
||||
use crate::idx::ft::highlighter::HighlightParams;
|
||||
use crate::sql::Value;
|
||||
use reblessive::tree::Stk;
|
||||
|
||||
pub async fn analyze(
|
||||
(stk, ctx, txn, opt): (&mut Stk, &Context<'_>, Option<&Transaction>, Option<&Options>),
|
||||
(stk, ctx, opt): (&mut Stk, &Context<'_>, Option<&Options>),
|
||||
(az, val): (Value, Value),
|
||||
) -> Result<Value, Error> {
|
||||
if let (Some(txn), Some(opt), Value::Strand(az), Value::Strand(val)) = (txn, opt, az, val) {
|
||||
if let (Some(opt), Value::Strand(az), Value::Strand(val)) = (opt, az, val) {
|
||||
let az: Analyzer =
|
||||
txn.lock().await.get_db_analyzer(opt.ns(), opt.db(), az.as_str()).await?.into();
|
||||
az.analyze(stk, ctx, opt, txn, val.0).await
|
||||
ctx.tx_lock().await.get_db_analyzer(opt.ns(), opt.db(), az.as_str()).await?.into();
|
||||
az.analyze(stk, ctx, opt, val.0).await
|
||||
} else {
|
||||
Ok(Value::None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn score(
|
||||
(ctx, txn, doc): (&Context<'_>, Option<&Transaction>, Option<&CursorDoc<'_>>),
|
||||
(ctx, doc): (&Context<'_>, Option<&CursorDoc<'_>>),
|
||||
(match_ref,): (Value,),
|
||||
) -> Result<Value, Error> {
|
||||
if let Some(txn) = txn {
|
||||
if let Some((exe, doc, thg)) = get_execution_context(ctx, doc) {
|
||||
return exe.score(txn, &match_ref, thg, doc.ir).await;
|
||||
}
|
||||
if let Some((exe, doc, thg)) = get_execution_context(ctx, doc) {
|
||||
return exe.score(ctx, &match_ref, thg, doc.ir).await;
|
||||
}
|
||||
Ok(Value::None)
|
||||
}
|
||||
|
||||
pub async fn highlight(
|
||||
(ctx, txn, doc): (&Context<'_>, Option<&Transaction>, Option<&CursorDoc<'_>>),
|
||||
(prefix, suffix, match_ref, partial): (Value, Value, Value, Option<Value>),
|
||||
(ctx, doc): (&Context<'_>, Option<&CursorDoc<'_>>),
|
||||
args: (Value, Value, Value, Option<Value>),
|
||||
) -> Result<Value, Error> {
|
||||
if let Some(txn) = txn {
|
||||
if let Some((exe, doc, thg)) = get_execution_context(ctx, doc) {
|
||||
let partial = partial.map(|p| p.convert_to_bool()).unwrap_or(Ok(false))?;
|
||||
return exe
|
||||
.highlight(txn, thg, prefix, suffix, match_ref, partial, doc.doc.as_ref())
|
||||
.await;
|
||||
}
|
||||
if let Some((exe, doc, thg)) = get_execution_context(ctx, doc) {
|
||||
let hlp: HighlightParams = args.try_into()?;
|
||||
return exe.highlight(ctx, thg, hlp, doc.doc.as_ref()).await;
|
||||
}
|
||||
Ok(Value::None)
|
||||
}
|
||||
|
||||
pub async fn offsets(
|
||||
(ctx, txn, doc): (&Context<'_>, Option<&Transaction>, Option<&CursorDoc<'_>>),
|
||||
(ctx, doc): (&Context<'_>, Option<&CursorDoc<'_>>),
|
||||
(match_ref, partial): (Value, Option<Value>),
|
||||
) -> Result<Value, Error> {
|
||||
if let Some(txn) = txn {
|
||||
if let Some((exe, _, thg)) = get_execution_context(ctx, doc) {
|
||||
let partial = partial.map(|p| p.convert_to_bool()).unwrap_or(Ok(false))?;
|
||||
return exe.offsets(txn, thg, match_ref, partial).await;
|
||||
}
|
||||
if let Some((exe, _, thg)) = get_execution_context(ctx, doc) {
|
||||
let partial = partial.map(|p| p.convert_to_bool()).unwrap_or(Ok(false))?;
|
||||
return exe.offsets(ctx, thg, match_ref, partial).await;
|
||||
}
|
||||
Ok(Value::None)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::ops::Bound;
|
||||
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::table::Table;
|
||||
|
@ -28,22 +28,16 @@ pub fn duration((val,): (Value,)) -> Result<Value, Error> {
|
|||
}
|
||||
|
||||
pub async fn field(
|
||||
(stk, ctx, opt, txn, doc): (
|
||||
&mut Stk,
|
||||
&Context<'_>,
|
||||
Option<&Options>,
|
||||
Option<&Transaction>,
|
||||
Option<&CursorDoc<'_>>,
|
||||
),
|
||||
(stk, ctx, opt, doc): (&mut Stk, &Context<'_>, Option<&Options>, Option<&CursorDoc<'_>>),
|
||||
(val,): (String,),
|
||||
) -> Result<Value, Error> {
|
||||
match (opt, txn) {
|
||||
(Some(opt), Some(txn)) => {
|
||||
match opt {
|
||||
Some(opt) => {
|
||||
// Parse the string as an Idiom
|
||||
let idi = syn::idiom(&val)?;
|
||||
// Return the Idiom or fetch the field
|
||||
match opt.projections {
|
||||
true => Ok(idi.compute(stk, ctx, opt, txn, doc).await?),
|
||||
true => Ok(idi.compute(stk, ctx, opt, doc).await?),
|
||||
false => Ok(idi.into()),
|
||||
}
|
||||
}
|
||||
|
@ -52,24 +46,18 @@ pub async fn field(
|
|||
}
|
||||
|
||||
pub async fn fields(
|
||||
(stk, ctx, opt, txn, doc): (
|
||||
&mut Stk,
|
||||
&Context<'_>,
|
||||
Option<&Options>,
|
||||
Option<&Transaction>,
|
||||
Option<&CursorDoc<'_>>,
|
||||
),
|
||||
(stk, ctx, opt, doc): (&mut Stk, &Context<'_>, Option<&Options>, Option<&CursorDoc<'_>>),
|
||||
(val,): (Vec<String>,),
|
||||
) -> Result<Value, Error> {
|
||||
match (opt, txn) {
|
||||
(Some(opt), Some(txn)) => {
|
||||
match opt {
|
||||
Some(opt) => {
|
||||
let mut args: Vec<Value> = Vec::with_capacity(val.len());
|
||||
for v in val {
|
||||
// Parse the string as an Idiom
|
||||
let idi = syn::idiom(&v)?;
|
||||
// Return the Idiom or fetch the field
|
||||
match opt.projections {
|
||||
true => args.push(idi.compute(stk, ctx, opt, txn, doc).await?),
|
||||
true => args.push(idi.compute(stk, ctx, opt, doc).await?),
|
||||
false => args.push(idi.into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::err::Error;
|
||||
use crate::idx::ft::analyzer::filter::FilteringStage;
|
||||
use crate::idx::ft::analyzer::tokenizer::{Tokenizer, Tokens};
|
||||
|
@ -64,17 +64,15 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
t: &Terms,
|
||||
content: String,
|
||||
) -> Result<(TermsList, TermsSet), Error> {
|
||||
let tokens =
|
||||
self.generate_tokens(stk, ctx, opt, txn, FilteringStage::Querying, content).await?;
|
||||
let tokens = self.generate_tokens(stk, ctx, opt, FilteringStage::Querying, content).await?;
|
||||
// We extract the term ids
|
||||
let mut list = Vec::with_capacity(tokens.list().len());
|
||||
let mut unique_tokens = HashSet::new();
|
||||
let mut set = HashSet::new();
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let mut has_unknown_terms = false;
|
||||
for token in tokens.list() {
|
||||
// Tokens can contains duplicated, not need to evaluate them again
|
||||
|
@ -104,15 +102,14 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
t: &Terms,
|
||||
content: Value,
|
||||
) -> Result<TermsSet, Error> {
|
||||
let mut tv = Vec::new();
|
||||
self.analyze_value(stk, ctx, opt, txn, content, FilteringStage::Indexing, &mut tv).await?;
|
||||
self.analyze_value(stk, ctx, opt, content, FilteringStage::Indexing, &mut tv).await?;
|
||||
let mut set = HashSet::new();
|
||||
let mut has_unknown_terms = false;
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
for tokens in tv {
|
||||
for token in tokens.list() {
|
||||
if let Some(term_id) =
|
||||
|
@ -138,7 +135,6 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
terms: &mut Terms,
|
||||
field_content: Vec<Value>,
|
||||
) -> Result<(DocLength, Vec<(TermId, TermFrequency)>), Error> {
|
||||
|
@ -146,16 +142,8 @@ impl Analyzer {
|
|||
// Let's first collect all the inputs, and collect the tokens.
|
||||
// We need to store them because everything after is zero-copy
|
||||
let mut inputs = vec![];
|
||||
self.analyze_content(
|
||||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
field_content,
|
||||
FilteringStage::Indexing,
|
||||
&mut inputs,
|
||||
)
|
||||
.await?;
|
||||
self.analyze_content(stk, ctx, opt, field_content, FilteringStage::Indexing, &mut inputs)
|
||||
.await?;
|
||||
// We then collect every unique terms and count the frequency
|
||||
let mut tf: HashMap<&str, TermFrequency> = HashMap::new();
|
||||
for tks in &inputs {
|
||||
|
@ -174,7 +162,7 @@ impl Analyzer {
|
|||
}
|
||||
// Now we can resolve the term ids
|
||||
let mut tfid = Vec::with_capacity(tf.len());
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
for (t, f) in tf {
|
||||
tfid.push((terms.resolve_term_id(&mut tx, t).await?, f));
|
||||
}
|
||||
|
@ -189,7 +177,6 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
terms: &mut Terms,
|
||||
content: Vec<Value>,
|
||||
) -> Result<(DocLength, Vec<(TermId, TermFrequency)>, Vec<(TermId, OffsetRecords)>), Error> {
|
||||
|
@ -197,8 +184,7 @@ impl Analyzer {
|
|||
// Let's first collect all the inputs, and collect the tokens.
|
||||
// We need to store them because everything after is zero-copy
|
||||
let mut inputs = Vec::with_capacity(content.len());
|
||||
self.analyze_content(stk, ctx, opt, txn, content, FilteringStage::Indexing, &mut inputs)
|
||||
.await?;
|
||||
self.analyze_content(stk, ctx, opt, content, FilteringStage::Indexing, &mut inputs).await?;
|
||||
// We then collect every unique terms and count the frequency and extract the offsets
|
||||
let mut tfos: HashMap<&str, Vec<Offset>> = HashMap::new();
|
||||
for (i, tks) in inputs.iter().enumerate() {
|
||||
|
@ -218,7 +204,7 @@ impl Analyzer {
|
|||
// Now we can resolve the term ids
|
||||
let mut tfid = Vec::with_capacity(tfos.len());
|
||||
let mut osid = Vec::with_capacity(tfos.len());
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
for (t, o) in tfos {
|
||||
let id = terms.resolve_term_id(&mut tx, t).await?;
|
||||
tfid.push((id, o.len() as TermFrequency));
|
||||
|
@ -229,53 +215,47 @@ impl Analyzer {
|
|||
}
|
||||
|
||||
/// Was marked recursive
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn analyze_content(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
content: Vec<Value>,
|
||||
stage: FilteringStage,
|
||||
tks: &mut Vec<Tokens>,
|
||||
) -> Result<(), Error> {
|
||||
for v in content {
|
||||
self.analyze_value(stk, ctx, opt, txn, v, stage, tks).await?;
|
||||
self.analyze_value(stk, ctx, opt, v, stage, tks).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Was marked recursive
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn analyze_value(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
val: Value,
|
||||
stage: FilteringStage,
|
||||
tks: &mut Vec<Tokens>,
|
||||
) -> Result<(), Error> {
|
||||
match val {
|
||||
Value::Strand(s) => {
|
||||
tks.push(self.generate_tokens(stk, ctx, opt, txn, stage, s.0).await?)
|
||||
}
|
||||
Value::Strand(s) => tks.push(self.generate_tokens(stk, ctx, opt, stage, s.0).await?),
|
||||
Value::Number(n) => {
|
||||
tks.push(self.generate_tokens(stk, ctx, opt, txn, stage, n.to_string()).await?)
|
||||
tks.push(self.generate_tokens(stk, ctx, opt, stage, n.to_string()).await?)
|
||||
}
|
||||
Value::Bool(b) => {
|
||||
tks.push(self.generate_tokens(stk, ctx, opt, txn, stage, b.to_string()).await?)
|
||||
tks.push(self.generate_tokens(stk, ctx, opt, stage, b.to_string()).await?)
|
||||
}
|
||||
Value::Array(a) => {
|
||||
for v in a.0 {
|
||||
stk.run(|stk| self.analyze_value(stk, ctx, opt, txn, v, stage, tks)).await?;
|
||||
stk.run(|stk| self.analyze_value(stk, ctx, opt, v, stage, tks)).await?;
|
||||
}
|
||||
}
|
||||
Value::Object(o) => {
|
||||
for (_, v) in o.0 {
|
||||
stk.run(|stk| self.analyze_value(stk, ctx, opt, txn, v, stage, tks)).await?;
|
||||
stk.run(|stk| self.analyze_value(stk, ctx, opt, v, stage, tks)).await?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -288,13 +268,12 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
stage: FilteringStage,
|
||||
mut input: String,
|
||||
) -> Result<Tokens, Error> {
|
||||
if let Some(function_name) = self.function.clone() {
|
||||
let fns = Function::Custom(function_name.clone(), vec![Value::Strand(Strand(input))]);
|
||||
let val = fns.compute(stk, ctx, opt, txn, None).await?;
|
||||
let val = fns.compute(stk, ctx, opt, None).await?;
|
||||
if let Value::Strand(val) = val {
|
||||
input = val.0;
|
||||
} else {
|
||||
|
@ -319,10 +298,9 @@ impl Analyzer {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
input: String,
|
||||
) -> Result<Value, Error> {
|
||||
self.generate_tokens(stk, ctx, opt, txn, FilteringStage::Indexing, input).await?.try_into()
|
||||
self.generate_tokens(stk, ctx, opt, FilteringStage::Indexing, input).await?.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,6 +323,7 @@ mod tests {
|
|||
let ds = Datastore::new("memory").await.unwrap();
|
||||
let tx = ds.transaction(TransactionType::Read, LockType::Optimistic).await.unwrap();
|
||||
let txn: Transaction = Arc::new(Mutex::new(tx));
|
||||
let ctx = Context::default().set_transaction(txn);
|
||||
|
||||
let mut stmt = syn::parse(&format!("DEFINE {def}")).unwrap();
|
||||
let Some(Statement::Define(DefineStatement::Analyzer(az))) = stmt.0 .0.pop() else {
|
||||
|
@ -354,18 +333,10 @@ mod tests {
|
|||
|
||||
let mut stack = reblessive::TreeStack::new();
|
||||
|
||||
let ctx = Context::default();
|
||||
let opts = Options::default();
|
||||
stack
|
||||
.enter(|stk| {
|
||||
a.generate_tokens(
|
||||
stk,
|
||||
&ctx,
|
||||
&opts,
|
||||
&txn,
|
||||
FilteringStage::Indexing,
|
||||
input.to_string(),
|
||||
)
|
||||
a.generate_tokens(stk, &ctx, &opts, FilteringStage::Indexing, input.to_string())
|
||||
})
|
||||
.finish()
|
||||
.await
|
||||
|
|
|
@ -6,6 +6,35 @@ use std::collections::hash_map::Entry as HEntry;
|
|||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub(crate) struct HighlightParams {
|
||||
prefix: Value,
|
||||
suffix: Value,
|
||||
match_ref: Value,
|
||||
partial: bool,
|
||||
}
|
||||
|
||||
impl TryFrom<(Value, Value, Value, Option<Value>)> for HighlightParams {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(
|
||||
(prefix, suffix, match_ref, partial): (Value, Value, Value, Option<Value>),
|
||||
) -> Result<Self, Error> {
|
||||
let partial = partial.map(|p| p.convert_to_bool()).unwrap_or(Ok(false))?;
|
||||
Ok(Self {
|
||||
prefix,
|
||||
suffix,
|
||||
match_ref,
|
||||
partial,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl HighlightParams {
|
||||
pub(crate) fn match_ref(&self) -> &Value {
|
||||
&self.match_ref
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct Highlighter {
|
||||
prefix: Vec<char>,
|
||||
suffix: Vec<char>,
|
||||
|
@ -14,22 +43,16 @@ pub(super) struct Highlighter {
|
|||
}
|
||||
|
||||
impl Highlighter {
|
||||
pub(super) fn new(
|
||||
prefix: Value,
|
||||
suffix: Value,
|
||||
partial: bool,
|
||||
idiom: &Idiom,
|
||||
doc: &Value,
|
||||
) -> Self {
|
||||
let prefix = prefix.to_raw_string().chars().collect();
|
||||
let suffix = suffix.to_raw_string().chars().collect();
|
||||
pub(super) fn new(hlp: HighlightParams, idiom: &Idiom, doc: &Value) -> Self {
|
||||
let prefix = hlp.prefix.to_raw_string().chars().collect();
|
||||
let suffix = hlp.suffix.to_raw_string().chars().collect();
|
||||
// Extract the fields we want to highlight
|
||||
let fields = doc.walk(idiom);
|
||||
Self {
|
||||
fields,
|
||||
prefix,
|
||||
suffix,
|
||||
offseter: Offseter::new(partial),
|
||||
offseter: Offseter::new(hlp.partial),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pub(crate) mod analyzer;
|
||||
mod doclength;
|
||||
mod highlighter;
|
||||
pub(crate) mod highlighter;
|
||||
mod offsets;
|
||||
mod postings;
|
||||
pub(super) mod scorer;
|
||||
|
@ -8,12 +8,12 @@ pub(super) mod termdocs;
|
|||
pub(crate) mod terms;
|
||||
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::err::Error;
|
||||
use crate::idx::docids::{DocId, DocIds};
|
||||
use crate::idx::ft::analyzer::{Analyzer, TermsList, TermsSet};
|
||||
use crate::idx::ft::doclength::DocLengths;
|
||||
use crate::idx::ft::highlighter::{Highlighter, Offseter};
|
||||
use crate::idx::ft::highlighter::{HighlightParams, Highlighter, Offseter};
|
||||
use crate::idx::ft::offsets::Offsets;
|
||||
use crate::idx::ft::postings::Postings;
|
||||
use crate::idx::ft::scorer::BM25Scorer;
|
||||
|
@ -98,17 +98,17 @@ impl VersionedSerdeState for State {}
|
|||
|
||||
impl FtIndex {
|
||||
pub(crate) async fn new(
|
||||
ixs: &IndexStores,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
az: &str,
|
||||
index_key_base: IndexKeyBase,
|
||||
p: &SearchParams,
|
||||
tt: TransactionType,
|
||||
) -> Result<Self, Error> {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let az = tx.get_db_analyzer(opt.ns(), opt.db(), az).await?;
|
||||
let res = Self::with_analyzer(ixs, &mut tx, az, index_key_base, p, tt).await;
|
||||
let res =
|
||||
Self::with_analyzer(ctx.get_index_stores(), &mut tx, az, index_key_base, p, tt).await;
|
||||
drop(tx);
|
||||
res
|
||||
}
|
||||
|
@ -191,10 +191,10 @@ impl FtIndex {
|
|||
|
||||
pub(crate) async fn remove_document(
|
||||
&mut self,
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
rid: &Thing,
|
||||
) -> Result<(), Error> {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
// Extract and remove the doc_id (if any)
|
||||
let mut doc_ids = self.doc_ids.write().await;
|
||||
let doc_id = doc_ids.remove_doc(&mut tx, rid.into()).await?;
|
||||
|
@ -244,12 +244,11 @@ impl FtIndex {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
rid: &Thing,
|
||||
content: Vec<Value>,
|
||||
) -> Result<(), Error> {
|
||||
// Resolve the doc_id
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let mut doc_ids = self.doc_ids.write().await;
|
||||
let resolved = doc_ids.resolve_doc_id(&mut tx, rid.into()).await?;
|
||||
drop(doc_ids);
|
||||
|
@ -261,19 +260,19 @@ impl FtIndex {
|
|||
let (doc_length, terms_and_frequencies, offsets) = if self.highlighting {
|
||||
let (dl, tf, ofs) = self
|
||||
.analyzer
|
||||
.extract_terms_with_frequencies_with_offsets(stk, ctx, opt, txn, &mut t, content)
|
||||
.extract_terms_with_frequencies_with_offsets(stk, ctx, opt, &mut t, content)
|
||||
.await?;
|
||||
(dl, tf, Some(ofs))
|
||||
} else {
|
||||
let (dl, tf) = self
|
||||
.analyzer
|
||||
.extract_terms_with_frequencies(stk, ctx, opt, txn, &mut t, content)
|
||||
.extract_terms_with_frequencies(stk, ctx, opt, &mut t, content)
|
||||
.await?;
|
||||
(dl, tf, None)
|
||||
};
|
||||
|
||||
// Set the doc length
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let mut dl = self.doc_lengths.write().await;
|
||||
if resolved.was_existing() {
|
||||
if let Some(old_doc_length) = dl.get_doc_length_mut(&mut tx, doc_id).await? {
|
||||
|
@ -356,12 +355,10 @@ impl FtIndex {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
query_string: String,
|
||||
) -> Result<(TermsList, TermsSet), Error> {
|
||||
let t = self.terms.read().await;
|
||||
let res =
|
||||
self.analyzer.extract_querying_terms(stk, ctx, opt, txn, &t, query_string).await?;
|
||||
let res = self.analyzer.extract_querying_terms(stk, ctx, opt, &t, query_string).await?;
|
||||
drop(t);
|
||||
Ok(res)
|
||||
}
|
||||
|
@ -425,15 +422,12 @@ impl FtIndex {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) async fn highlight(
|
||||
&self,
|
||||
tx: &mut kvs::Transaction,
|
||||
thg: &Thing,
|
||||
terms: &[Option<(TermId, TermLen)>],
|
||||
prefix: Value,
|
||||
suffix: Value,
|
||||
partial: bool,
|
||||
hlp: HighlightParams,
|
||||
idiom: &Idiom,
|
||||
doc: &Value,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -442,7 +436,7 @@ impl FtIndex {
|
|||
let doc_id = di.get_doc_id(tx, doc_key).await?;
|
||||
drop(di);
|
||||
if let Some(doc_id) = doc_id {
|
||||
let mut hl = Highlighter::new(prefix, suffix, partial, idiom, doc);
|
||||
let mut hl = Highlighter::new(hlp, idiom, doc);
|
||||
for (term_id, term_len) in terms.iter().flatten() {
|
||||
let o = self.offsets.get_offsets(tx, doc_id, *term_id).await?;
|
||||
if let Some(o) = o {
|
||||
|
@ -478,9 +472,9 @@ impl FtIndex {
|
|||
Ok(Value::None)
|
||||
}
|
||||
|
||||
pub(crate) async fn statistics(&self, txn: &Transaction) -> Result<FtStatistics, Error> {
|
||||
pub(crate) async fn statistics(&self, ctx: &Context<'_>) -> Result<FtStatistics, Error> {
|
||||
// TODO do parallel execution
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
let res = FtStatistics {
|
||||
doc_ids: self.doc_ids.read().await.statistics(&mut run).await?,
|
||||
terms: self.terms.read().await.statistics(&mut run).await?,
|
||||
|
@ -491,8 +485,8 @@ impl FtIndex {
|
|||
Ok(res)
|
||||
}
|
||||
|
||||
pub(crate) async fn finish(&self, tx: &Transaction) -> Result<(), Error> {
|
||||
let mut run = tx.lock().await;
|
||||
pub(crate) async fn finish(&self, ctx: &Context<'_>) -> Result<(), Error> {
|
||||
let mut run = ctx.tx_lock().await;
|
||||
self.doc_ids.write().await.finish(&mut run).await?;
|
||||
self.doc_lengths.write().await.finish(&mut run).await?;
|
||||
self.postings.write().await.finish(&mut run).await?;
|
||||
|
@ -543,7 +537,7 @@ impl HitsIterator {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::idx::ft::scorer::{BM25Scorer, Score};
|
||||
use crate::idx::ft::{FtIndex, HitsIterator};
|
||||
use crate::idx::IndexKeyBase;
|
||||
|
@ -559,12 +553,12 @@ mod tests {
|
|||
use test_log::test;
|
||||
|
||||
async fn check_hits(
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
hits: Option<HitsIterator>,
|
||||
scr: BM25Scorer,
|
||||
e: Vec<(&Thing, Option<Score>)>,
|
||||
) {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
if let Some(mut hits) = hits {
|
||||
let mut map = HashMap::new();
|
||||
while let Some((k, d)) = hits.next(&mut tx).await.unwrap() {
|
||||
|
@ -585,13 +579,12 @@ mod tests {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
fti: &FtIndex,
|
||||
qs: &str,
|
||||
) -> (Option<HitsIterator>, BM25Scorer) {
|
||||
let (term_list, _) =
|
||||
fti.extract_querying_terms(stk, ctx, opt, txn, qs.to_string()).await.unwrap();
|
||||
let mut tx = txn.lock().await;
|
||||
fti.extract_querying_terms(stk, ctx, opt, qs.to_string()).await.unwrap();
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let td = Arc::new(fti.get_terms_docs(&mut tx, &term_list).await.unwrap());
|
||||
drop(tx);
|
||||
let scr = fti.new_scorer(td.clone()).unwrap().unwrap();
|
||||
|
@ -605,11 +598,9 @@ mod tests {
|
|||
az: &DefineAnalyzerStatement,
|
||||
order: u32,
|
||||
hl: bool,
|
||||
) -> (Context<'a>, Options, Transaction, FtIndex) {
|
||||
let ctx = Context::default();
|
||||
let tx = ds.transaction(tt, Optimistic).await.unwrap();
|
||||
let txn = Arc::new(Mutex::new(tx));
|
||||
let mut tx = txn.lock().await;
|
||||
) -> (Context<'a>, Options, FtIndex) {
|
||||
let mut ctx = Context::default();
|
||||
let mut tx = ds.transaction(tt, Optimistic).await.unwrap();
|
||||
let fti = FtIndex::with_analyzer(
|
||||
ctx.get_index_stores(),
|
||||
&mut tx,
|
||||
|
@ -632,15 +623,15 @@ mod tests {
|
|||
)
|
||||
.await
|
||||
.unwrap();
|
||||
drop(tx);
|
||||
(ctx, Options::default(), txn, fti)
|
||||
let txn = Arc::new(Mutex::new(tx));
|
||||
ctx.set_transaction_mut(txn);
|
||||
(ctx, Options::default(), fti)
|
||||
}
|
||||
|
||||
pub(super) async fn finish(txn: &Transaction, fti: FtIndex) {
|
||||
fti.finish(txn).await.unwrap();
|
||||
let mut tx = txn.lock().await;
|
||||
pub(super) async fn finish(ctx: &Context<'_>, fti: FtIndex) {
|
||||
fti.finish(ctx).await.unwrap();
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
tx.commit().await.unwrap();
|
||||
drop(tx);
|
||||
}
|
||||
|
||||
#[test(tokio::test)]
|
||||
|
@ -661,19 +652,12 @@ mod tests {
|
|||
stack
|
||||
.enter(|stk| async {
|
||||
// Add one document
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
let (ctx, opt, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, btree_order, false).await;
|
||||
fti.index_document(
|
||||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc1,
|
||||
vec![Value::from("hello the world")],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
fti.index_document(stk, &ctx, &opt, &doc1, vec![Value::from("hello the world")])
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&ctx, fti).await;
|
||||
})
|
||||
.finish()
|
||||
.await;
|
||||
|
@ -681,60 +665,53 @@ mod tests {
|
|||
stack
|
||||
.enter(|stk| async {
|
||||
// Add two documents
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
let (ctx, opt, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, btree_order, false).await;
|
||||
fti.index_document(
|
||||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc2,
|
||||
vec![Value::from("a yellow hello")],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
fti.index_document(stk, &ctx, &opt, &txn, &doc3, vec![Value::from("foo bar")])
|
||||
fti.index_document(stk, &ctx, &opt, &doc2, vec![Value::from("a yellow hello")])
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
fti.index_document(stk, &ctx, &opt, &doc3, vec![Value::from("foo bar")])
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&ctx, fti).await;
|
||||
})
|
||||
.finish()
|
||||
.await;
|
||||
|
||||
stack
|
||||
.enter(|stk| async {
|
||||
let (ctx, opt, txn, fti) =
|
||||
let (ctx, opt, fti) =
|
||||
tx_fti(&ds, TransactionType::Read, &az, btree_order, false).await;
|
||||
// Check the statistics
|
||||
let statistics = fti.statistics(&txn).await.unwrap();
|
||||
let statistics = fti.statistics(&ctx).await.unwrap();
|
||||
assert_eq!(statistics.terms.keys_count, 7);
|
||||
assert_eq!(statistics.postings.keys_count, 8);
|
||||
assert_eq!(statistics.doc_ids.keys_count, 3);
|
||||
assert_eq!(statistics.doc_lengths.keys_count, 3);
|
||||
|
||||
// Search & score
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "hello").await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "hello").await;
|
||||
check_hits(
|
||||
&txn,
|
||||
&ctx,
|
||||
hits,
|
||||
scr,
|
||||
vec![(&doc1, Some(-0.4859746)), (&doc2, Some(-0.4859746))],
|
||||
)
|
||||
.await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "world").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc1, Some(0.4859746))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "world").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc1, Some(0.4859746))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "yellow").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc2, Some(0.4859746))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "yellow").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc2, Some(0.4859746))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "foo").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "foo").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "bar").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "bar").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
|
||||
let (hits, _) = search(stk, &ctx, &opt, &txn, &fti, "dummy").await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &fti, "dummy").await;
|
||||
assert!(hits.is_none());
|
||||
})
|
||||
.finish()
|
||||
|
@ -743,48 +720,48 @@ mod tests {
|
|||
stack
|
||||
.enter(|stk| async {
|
||||
// Reindex one document
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
let (ctx, opt, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, btree_order, false).await;
|
||||
fti.index_document(stk, &ctx, &opt, &txn, &doc3, vec![Value::from("nobar foo")])
|
||||
fti.index_document(stk, &ctx, &opt, &doc3, vec![Value::from("nobar foo")])
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
finish(&ctx, fti).await;
|
||||
|
||||
let (ctx, opt, txn, fti) =
|
||||
let (ctx, opt, fti) =
|
||||
tx_fti(&ds, TransactionType::Read, &az, btree_order, false).await;
|
||||
|
||||
// We can still find 'foo'
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "foo").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "foo").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
|
||||
// We can't anymore find 'bar'
|
||||
let (hits, _) = search(stk, &ctx, &opt, &txn, &fti, "bar").await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &fti, "bar").await;
|
||||
assert!(hits.is_none());
|
||||
|
||||
// We can now find 'nobar'
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "nobar").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "nobar").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc3, Some(0.56902087))]).await;
|
||||
})
|
||||
.finish()
|
||||
.await;
|
||||
|
||||
{
|
||||
// Remove documents
|
||||
let (_, _, txn, mut fti) =
|
||||
let (ctx, _, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, btree_order, false).await;
|
||||
fti.remove_document(&txn, &doc1).await.unwrap();
|
||||
fti.remove_document(&txn, &doc2).await.unwrap();
|
||||
fti.remove_document(&txn, &doc3).await.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
fti.remove_document(&ctx, &doc1).await.unwrap();
|
||||
fti.remove_document(&ctx, &doc2).await.unwrap();
|
||||
fti.remove_document(&ctx, &doc3).await.unwrap();
|
||||
finish(&ctx, fti).await;
|
||||
}
|
||||
|
||||
stack
|
||||
.enter(|stk| async {
|
||||
let (ctx, opt, txn, fti) =
|
||||
let (ctx, opt, fti) =
|
||||
tx_fti(&ds, TransactionType::Read, &az, btree_order, false).await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &txn, &fti, "hello").await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &fti, "hello").await;
|
||||
assert!(hits.is_none());
|
||||
let (hits, _) = search(stk, &ctx, &opt, &txn, &fti, "foo").await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &fti, "foo").await;
|
||||
assert!(hits.is_none());
|
||||
})
|
||||
.finish()
|
||||
|
@ -812,13 +789,12 @@ mod tests {
|
|||
let btree_order = 5;
|
||||
stack
|
||||
.enter(|stk| async {
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
let (ctx, opt, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, btree_order, hl).await;
|
||||
fti.index_document(
|
||||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc1,
|
||||
vec![Value::from("the quick brown fox jumped over the lazy dog")],
|
||||
)
|
||||
|
@ -828,7 +804,6 @@ mod tests {
|
|||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc2,
|
||||
vec![Value::from("the fast fox jumped over the lazy dog")],
|
||||
)
|
||||
|
@ -838,7 +813,6 @@ mod tests {
|
|||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc3,
|
||||
vec![Value::from("the dog sat there and did nothing")],
|
||||
)
|
||||
|
@ -848,31 +822,30 @@ mod tests {
|
|||
stk,
|
||||
&ctx,
|
||||
&opt,
|
||||
&txn,
|
||||
&doc4,
|
||||
vec![Value::from("the other animals sat there watching")],
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
finish(&ctx, fti).await;
|
||||
})
|
||||
.finish()
|
||||
.await;
|
||||
|
||||
stack
|
||||
.enter(|stk| async {
|
||||
let (ctx, opt, txn, fti) =
|
||||
let (ctx, opt, fti) =
|
||||
tx_fti(&ds, TransactionType::Read, &az, btree_order, hl).await;
|
||||
|
||||
let statistics = fti.statistics(&txn).await.unwrap();
|
||||
let statistics = fti.statistics(&ctx).await.unwrap();
|
||||
assert_eq!(statistics.terms.keys_count, 17);
|
||||
assert_eq!(statistics.postings.keys_count, 28);
|
||||
assert_eq!(statistics.doc_ids.keys_count, 4);
|
||||
assert_eq!(statistics.doc_lengths.keys_count, 4);
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "the").await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "the").await;
|
||||
check_hits(
|
||||
&txn,
|
||||
&ctx,
|
||||
hits,
|
||||
scr,
|
||||
vec![
|
||||
|
@ -884,9 +857,9 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "dog").await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "dog").await;
|
||||
check_hits(
|
||||
&txn,
|
||||
&ctx,
|
||||
hits,
|
||||
scr,
|
||||
vec![
|
||||
|
@ -897,25 +870,25 @@ mod tests {
|
|||
)
|
||||
.await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "fox").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "fox").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "over").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "over").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "lazy").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "lazy").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "jumped").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "jumped").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc1, Some(0.0)), (&doc2, Some(0.0))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "nothing").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc3, Some(0.87105393))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "nothing").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc3, Some(0.87105393))]).await;
|
||||
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &txn, &fti, "animals").await;
|
||||
check_hits(&txn, hits, scr, vec![(&doc4, Some(0.92279965))]).await;
|
||||
let (hits, scr) = search(stk, &ctx, &opt, &fti, "animals").await;
|
||||
check_hits(&ctx, hits, scr, vec![(&doc4, Some(0.92279965))]).await;
|
||||
|
||||
let (hits, _) = search(stk, &ctx, &opt, &txn, &fti, "dummy").await;
|
||||
let (hits, _) = search(stk, &ctx, &opt, &fti, "dummy").await;
|
||||
assert!(hits.is_none());
|
||||
})
|
||||
.finish()
|
||||
|
@ -970,11 +943,10 @@ mod tests {
|
|||
rid: &Thing,
|
||||
content: &Value,
|
||||
) {
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
tx_fti(ds, TransactionType::Write, az, btree_order, false).await;
|
||||
fti.remove_document(&txn, rid).await.unwrap();
|
||||
fti.index_document(stk, &ctx, &opt, &txn, rid, vec![content.clone()]).await.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
let (ctx, opt, mut fti) = tx_fti(ds, TransactionType::Write, az, btree_order, false).await;
|
||||
fti.remove_document(&ctx, rid).await.unwrap();
|
||||
fti.index_document(stk, &ctx, &opt, rid, vec![content.clone()]).await.unwrap();
|
||||
finish(&ctx, fti).await;
|
||||
}
|
||||
|
||||
#[test(tokio::test)]
|
||||
|
@ -991,33 +963,30 @@ mod tests {
|
|||
for i in 0..5 {
|
||||
debug!("Attempt {i}");
|
||||
{
|
||||
let (ctx, opt, txn, mut fti) =
|
||||
tx_fti(&ds, TransactionType::Write, &az, 5, false).await;
|
||||
let (ctx, opt, mut fti) = tx_fti(&ds, TransactionType::Write, &az, 5, false).await;
|
||||
stack
|
||||
.enter(|stk| {
|
||||
fti.index_document(stk, &ctx, &opt, &txn, &doc, vec![content.clone()])
|
||||
})
|
||||
.enter(|stk| fti.index_document(stk, &ctx, &opt, &doc, vec![content.clone()]))
|
||||
.finish()
|
||||
.await
|
||||
.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
finish(&ctx, fti).await;
|
||||
}
|
||||
|
||||
{
|
||||
let (_, _, txn, fti) = tx_fti(&ds, TransactionType::Read, &az, 5, false).await;
|
||||
let s = fti.statistics(&txn).await.unwrap();
|
||||
let (ctx, _, fti) = tx_fti(&ds, TransactionType::Read, &az, 5, false).await;
|
||||
let s = fti.statistics(&ctx).await.unwrap();
|
||||
assert_eq!(s.terms.keys_count, 113);
|
||||
}
|
||||
|
||||
{
|
||||
let (_, _, txn, mut fti) = tx_fti(&ds, TransactionType::Write, &az, 5, false).await;
|
||||
fti.remove_document(&txn, &doc).await.unwrap();
|
||||
finish(&txn, fti).await;
|
||||
let (ctx, _, mut fti) = tx_fti(&ds, TransactionType::Write, &az, 5, false).await;
|
||||
fti.remove_document(&ctx, &doc).await.unwrap();
|
||||
finish(&ctx, fti).await;
|
||||
}
|
||||
|
||||
{
|
||||
let (_, _, txn, fti) = tx_fti(&ds, TransactionType::Read, &az, 5, false).await;
|
||||
let s = fti.statistics(&txn).await.unwrap();
|
||||
let (ctx, _, fti) = tx_fti(&ds, TransactionType::Read, &az, 5, false).await;
|
||||
let s = fti.statistics(&ctx).await.unwrap();
|
||||
assert_eq!(s.terms.keys_count, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Iterable, Options, Transaction};
|
||||
use crate::dbs::{Iterable, Options};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::idx::docids::{DocId, DocIds};
|
||||
|
@ -32,15 +32,13 @@ impl<'a> Default for HnswConditionChecker<'a> {
|
|||
|
||||
impl<'a> HnswConditionChecker<'a> {
|
||||
pub(in crate::idx) fn new_cond(
|
||||
ctx: &'a Context<'a>,
|
||||
ctx: &'a Context<'_>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
cond: Arc<Cond>,
|
||||
) -> Self {
|
||||
Self::HnswCondition(HnswCondChecker {
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
cond,
|
||||
cache: Default::default(),
|
||||
})
|
||||
|
@ -83,28 +81,22 @@ impl<'a> HnswConditionChecker<'a> {
|
|||
}
|
||||
|
||||
impl<'a> MTreeConditionChecker<'a> {
|
||||
pub fn new_cond(
|
||||
ctx: &'a Context<'_>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
cond: Arc<Cond>,
|
||||
) -> Self {
|
||||
pub fn new_cond(ctx: &'a Context<'_>, opt: &'a Options, cond: Arc<Cond>) -> Self {
|
||||
if Cond(Value::Bool(true)).ne(cond.as_ref()) {
|
||||
return Self::MTreeCondition(MTreeCondChecker {
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
cond,
|
||||
cache: Default::default(),
|
||||
});
|
||||
} else {
|
||||
Self::new(txn)
|
||||
Self::new(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(txn: &'a Transaction) -> Self {
|
||||
pub fn new(ctx: &'a Context<'a>) -> Self {
|
||||
Self::MTree(MTreeChecker {
|
||||
txn,
|
||||
ctx,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -139,7 +131,7 @@ impl<'a> MTreeConditionChecker<'a> {
|
|||
}
|
||||
|
||||
pub struct MTreeChecker<'a> {
|
||||
txn: &'a Transaction,
|
||||
ctx: &'a Context<'a>,
|
||||
}
|
||||
|
||||
impl<'a> MTreeChecker<'a> {
|
||||
|
@ -152,7 +144,7 @@ impl<'a> MTreeChecker<'a> {
|
|||
return Ok(VecDeque::from([]));
|
||||
}
|
||||
let mut result = VecDeque::with_capacity(res.len());
|
||||
let mut tx = self.txn.lock().await;
|
||||
let mut tx = self.ctx.tx_lock().await;
|
||||
for (doc_id, dist) in res {
|
||||
if let Some(key) = doc_ids.get_doc_key(&mut tx, doc_id).await? {
|
||||
result.push_back((key.into(), dist, None));
|
||||
|
@ -190,12 +182,11 @@ impl CheckerCacheEntry {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
rid: Option<Thing>,
|
||||
cond: &Cond,
|
||||
) -> Result<Self, Error> {
|
||||
if let Some(rid) = rid {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let val = Iterable::fetch_thing(&mut tx, opt, &rid).await?;
|
||||
drop(tx);
|
||||
if !val.is_none_or_null() {
|
||||
|
@ -205,8 +196,7 @@ impl CheckerCacheEntry {
|
|||
ir: None,
|
||||
doc: Cow::Owned(val),
|
||||
};
|
||||
let truthy =
|
||||
cond.compute(stk, ctx, opt, txn, Some(&cursor_doc)).await?.is_truthy();
|
||||
let truthy = cond.compute(stk, ctx, opt, Some(&cursor_doc)).await?.is_truthy();
|
||||
(cursor_doc.doc.into_owned(), truthy)
|
||||
};
|
||||
return Ok(CheckerCacheEntry {
|
||||
|
@ -225,7 +215,6 @@ impl CheckerCacheEntry {
|
|||
pub struct MTreeCondChecker<'a> {
|
||||
ctx: &'a Context<'a>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
cond: Arc<Cond>,
|
||||
cache: HashMap<DocId, CheckerCacheEntry>,
|
||||
}
|
||||
|
@ -240,18 +229,12 @@ impl<'a> MTreeCondChecker<'a> {
|
|||
match self.cache.entry(doc_id) {
|
||||
Entry::Occupied(e) => Ok(e.get().truthy),
|
||||
Entry::Vacant(e) => {
|
||||
let mut tx = self.txn.lock().await;
|
||||
let mut tx = self.ctx.tx_lock().await;
|
||||
let rid = doc_ids.get_doc_key(&mut tx, doc_id).await?.map(|k| k.into());
|
||||
drop(tx);
|
||||
let ent = CheckerCacheEntry::build(
|
||||
stk,
|
||||
self.ctx,
|
||||
self.opt,
|
||||
self.txn,
|
||||
rid,
|
||||
self.cond.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
let ent =
|
||||
CheckerCacheEntry::build(stk, self.ctx, self.opt, rid, self.cond.as_ref())
|
||||
.await?;
|
||||
let truthy = ent.truthy;
|
||||
e.insert(ent);
|
||||
Ok(truthy)
|
||||
|
@ -298,7 +281,6 @@ impl<'a> HnswChecker {
|
|||
pub struct HnswCondChecker<'a> {
|
||||
ctx: &'a Context<'a>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
cond: Arc<Cond>,
|
||||
cache: HashMap<DocId, CheckerCacheEntry>,
|
||||
}
|
||||
|
@ -320,15 +302,9 @@ impl<'a> HnswCondChecker<'a> {
|
|||
Entry::Occupied(e) => e.get().truthy,
|
||||
Entry::Vacant(e) => {
|
||||
let rid: Option<Thing> = docs.get_thing(doc_id).cloned();
|
||||
let ent = CheckerCacheEntry::build(
|
||||
stk,
|
||||
self.ctx,
|
||||
self.opt,
|
||||
self.txn,
|
||||
rid,
|
||||
self.cond.as_ref(),
|
||||
)
|
||||
.await?;
|
||||
let ent =
|
||||
CheckerCacheEntry::build(stk, self.ctx, self.opt, rid, self.cond.as_ref())
|
||||
.await?;
|
||||
let truthy = ent.truthy;
|
||||
e.insert(ent);
|
||||
truthy
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::idx::docids::DocIds;
|
||||
use crate::idx::ft::analyzer::{Analyzer, TermsList, TermsSet};
|
||||
use crate::idx::ft::highlighter::HighlightParams;
|
||||
use crate::idx::ft::scorer::BM25Scorer;
|
||||
use crate::idx::ft::termdocs::TermsDocs;
|
||||
use crate::idx::ft::terms::Terms;
|
||||
|
@ -105,7 +106,6 @@ impl InnerQueryExecutor {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
table: &Table,
|
||||
im: IndexesMap,
|
||||
knns: KnnExpressions,
|
||||
|
@ -130,22 +130,19 @@ impl InnerQueryExecutor {
|
|||
match &idx_def.index {
|
||||
Index::Search(p) => {
|
||||
let ft_entry = match ft_map.entry(ix_ref) {
|
||||
Entry::Occupied(e) => {
|
||||
FtEntry::new(stk, ctx, opt, txn, e.get(), io).await?
|
||||
}
|
||||
Entry::Occupied(e) => FtEntry::new(stk, ctx, opt, e.get(), io).await?,
|
||||
Entry::Vacant(e) => {
|
||||
let ikb = IndexKeyBase::new(opt, idx_def);
|
||||
let ft = FtIndex::new(
|
||||
ctx.get_index_stores(),
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
p.az.as_str(),
|
||||
ikb,
|
||||
p,
|
||||
TransactionType::Read,
|
||||
)
|
||||
.await?;
|
||||
let fte = FtEntry::new(stk, ctx, opt, txn, &ft, io).await?;
|
||||
let fte = FtEntry::new(stk, ctx, opt, &ft, io).await?;
|
||||
e.insert(ft);
|
||||
fte
|
||||
}
|
||||
|
@ -169,7 +166,6 @@ impl InnerQueryExecutor {
|
|||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
e.get(),
|
||||
a,
|
||||
*k,
|
||||
|
@ -179,7 +175,7 @@ impl InnerQueryExecutor {
|
|||
}
|
||||
Entry::Vacant(e) => {
|
||||
let ikb = IndexKeyBase::new(opt, idx_def);
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let mt = MTreeIndex::new(
|
||||
ctx.get_index_stores(),
|
||||
&mut tx,
|
||||
|
@ -193,7 +189,6 @@ impl InnerQueryExecutor {
|
|||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
&mt,
|
||||
a,
|
||||
*k,
|
||||
|
@ -215,7 +210,6 @@ impl InnerQueryExecutor {
|
|||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
e.get().clone(),
|
||||
a,
|
||||
*k,
|
||||
|
@ -233,7 +227,6 @@ impl InnerQueryExecutor {
|
|||
stk,
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
hnsw.clone(),
|
||||
a,
|
||||
*k,
|
||||
|
@ -279,13 +272,11 @@ impl InnerQueryExecutor {
|
|||
}
|
||||
|
||||
impl QueryExecutor {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn knn(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
thg: &Thing,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
exp: &Expression,
|
||||
|
@ -297,7 +288,7 @@ impl QueryExecutor {
|
|||
Ok(Value::Bool(false))
|
||||
} else {
|
||||
if let Some((p, id, val, dist)) = self.0.knn_bruteforce_entries.get(exp) {
|
||||
let v: Vec<Number> = id.compute(stk, ctx, opt, txn, doc).await?.try_into()?;
|
||||
let v: Vec<Number> = id.compute(stk, ctx, opt, doc).await?.try_into()?;
|
||||
let dist = dist.compute(&v, val.as_ref())?;
|
||||
p.add(dist, thg).await;
|
||||
}
|
||||
|
@ -538,7 +529,6 @@ impl QueryExecutor {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
thg: &Thing,
|
||||
exp: &Expression,
|
||||
l: Value,
|
||||
|
@ -547,10 +537,10 @@ impl QueryExecutor {
|
|||
if let Some(ft) = self.0.exp_entries.get(exp) {
|
||||
if let Some(ix_def) = self.get_index_def(ft.0.index_option.ix_ref()) {
|
||||
if self.0.table.eq(&ix_def.what.0) {
|
||||
return self.matches_with_doc_id(txn, thg, ft).await;
|
||||
return self.matches_with_doc_id(ctx, thg, ft).await;
|
||||
}
|
||||
}
|
||||
return self.matches_with_value(stk, ctx, opt, txn, ft, l, r).await;
|
||||
return self.matches_with_value(stk, ctx, opt, ft, l, r).await;
|
||||
}
|
||||
|
||||
// If no previous case were successful, we end up with a user error
|
||||
|
@ -561,12 +551,12 @@ impl QueryExecutor {
|
|||
|
||||
async fn matches_with_doc_id(
|
||||
&self,
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
thg: &Thing,
|
||||
ft: &FtEntry,
|
||||
) -> Result<bool, Error> {
|
||||
let doc_key: Key = thg.into();
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
let di = ft.0.doc_ids.read().await;
|
||||
let doc_id = di.get_doc_id(&mut run, doc_key).await?;
|
||||
drop(di);
|
||||
|
@ -592,13 +582,11 @@ impl QueryExecutor {
|
|||
Ok(false)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn matches_with_value(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
ft: &FtEntry,
|
||||
l: Value,
|
||||
r: Value,
|
||||
|
@ -615,7 +603,7 @@ impl QueryExecutor {
|
|||
};
|
||||
let terms = ft.0.terms.read().await;
|
||||
// Extract the terms set from the record
|
||||
let t = ft.0.analyzer.extract_indexing_terms(stk, ctx, opt, txn, &terms, v).await?;
|
||||
let t = ft.0.analyzer.extract_indexing_terms(stk, ctx, opt, &terms, v).await?;
|
||||
drop(terms);
|
||||
Ok(ft.0.query_terms_set.is_subset(&t))
|
||||
}
|
||||
|
@ -637,27 +625,21 @@ impl QueryExecutor {
|
|||
None
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn highlight(
|
||||
&self,
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
thg: &Thing,
|
||||
prefix: Value,
|
||||
suffix: Value,
|
||||
match_ref: Value,
|
||||
partial: bool,
|
||||
hlp: HighlightParams,
|
||||
doc: &Value,
|
||||
) -> Result<Value, Error> {
|
||||
if let Some((e, ft)) = self.get_ft_entry_and_index(&match_ref) {
|
||||
let mut run = txn.lock().await;
|
||||
if let Some((e, ft)) = self.get_ft_entry_and_index(hlp.match_ref()) {
|
||||
let mut run = ctx.tx_lock().await;
|
||||
let res = ft
|
||||
.highlight(
|
||||
&mut run,
|
||||
thg,
|
||||
&e.0.query_terms_list,
|
||||
prefix,
|
||||
suffix,
|
||||
partial,
|
||||
hlp,
|
||||
e.0.index_option.id_ref(),
|
||||
doc,
|
||||
)
|
||||
|
@ -670,13 +652,13 @@ impl QueryExecutor {
|
|||
|
||||
pub(crate) async fn offsets(
|
||||
&self,
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
thg: &Thing,
|
||||
match_ref: Value,
|
||||
partial: bool,
|
||||
) -> Result<Value, Error> {
|
||||
if let Some((e, ft)) = self.get_ft_entry_and_index(&match_ref) {
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
let res = ft.extract_offsets(&mut run, thg, &e.0.query_terms_list, partial).await;
|
||||
drop(run);
|
||||
return res;
|
||||
|
@ -686,14 +668,14 @@ impl QueryExecutor {
|
|||
|
||||
pub(crate) async fn score(
|
||||
&self,
|
||||
txn: &Transaction,
|
||||
ctx: &Context<'_>,
|
||||
match_ref: &Value,
|
||||
rid: &Thing,
|
||||
ir: Option<&IteratorRecord>,
|
||||
) -> Result<Value, Error> {
|
||||
if let Some(e) = self.get_ft_entry(match_ref) {
|
||||
if let Some(scorer) = &e.0.scorer {
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
let mut doc_id = if let Some(ir) = ir {
|
||||
ir.doc_id()
|
||||
} else {
|
||||
|
@ -738,14 +720,13 @@ impl FtEntry {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
ft: &FtIndex,
|
||||
io: IndexOption,
|
||||
) -> Result<Option<Self>, Error> {
|
||||
if let Matches(qs, _) = io.op() {
|
||||
let (terms_list, terms_set) =
|
||||
ft.extract_querying_terms(stk, ctx, opt, txn, qs.to_owned()).await?;
|
||||
let mut tx = txn.lock().await;
|
||||
ft.extract_querying_terms(stk, ctx, opt, qs.to_owned()).await?;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let terms_docs = Arc::new(ft.get_terms_docs(&mut tx, &terms_list).await?);
|
||||
drop(tx);
|
||||
Ok(Some(Self(Arc::new(Inner {
|
||||
|
@ -770,23 +751,21 @@ pub(super) struct MtEntry {
|
|||
}
|
||||
|
||||
impl MtEntry {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn new(
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
mt: &MTreeIndex,
|
||||
o: &[Number],
|
||||
k: u32,
|
||||
cond: Option<Arc<Cond>>,
|
||||
) -> Result<Self, Error> {
|
||||
let cond_checker = if let Some(cond) = cond {
|
||||
MTreeConditionChecker::new_cond(ctx, opt, txn, cond)
|
||||
MTreeConditionChecker::new_cond(ctx, opt, cond)
|
||||
} else {
|
||||
MTreeConditionChecker::new(txn)
|
||||
MTreeConditionChecker::new(ctx)
|
||||
};
|
||||
let res = mt.knn_search(stk, txn, o, k as usize, cond_checker).await?;
|
||||
let res = mt.knn_search(stk, ctx, o, k as usize, cond_checker).await?;
|
||||
Ok(Self {
|
||||
res,
|
||||
})
|
||||
|
@ -804,7 +783,6 @@ impl HnswEntry {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
h: SharedHnswIndex,
|
||||
v: &[Number],
|
||||
n: u32,
|
||||
|
@ -812,7 +790,7 @@ impl HnswEntry {
|
|||
cond: Option<Arc<Cond>>,
|
||||
) -> Result<Self, Error> {
|
||||
let cond_checker = if let Some(cond) = cond {
|
||||
HnswConditionChecker::new_cond(ctx, opt, txn, cond)
|
||||
HnswConditionChecker::new_cond(ctx, opt, cond)
|
||||
} else {
|
||||
HnswConditionChecker::default()
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ pub(in crate::idx) mod rewriter;
|
|||
pub(in crate::idx) mod tree;
|
||||
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Iterable, Iterator, Options, Transaction};
|
||||
use crate::dbs::{Iterable, Iterator, Options};
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::executor::{InnerQueryExecutor, IteratorEntry, QueryExecutor};
|
||||
use crate::idx::planner::iterators::IteratorRef;
|
||||
|
@ -50,20 +50,18 @@ impl<'a> QueryPlanner<'a> {
|
|||
&mut self,
|
||||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
txn: &Transaction,
|
||||
t: Table,
|
||||
it: &mut Iterator,
|
||||
) -> Result<(), Error> {
|
||||
let mut is_table_iterator = false;
|
||||
let mut is_knn = false;
|
||||
match Tree::build(stk, ctx, self.opt, txn, &t, self.cond, self.with).await? {
|
||||
match Tree::build(stk, ctx, self.opt, &t, self.cond, self.with).await? {
|
||||
Some(tree) => {
|
||||
is_knn = is_knn || !tree.knn_expressions.is_empty();
|
||||
let mut exe = InnerQueryExecutor::new(
|
||||
stk,
|
||||
ctx,
|
||||
self.opt,
|
||||
txn,
|
||||
&t,
|
||||
tree.index_map,
|
||||
tree.knn_expressions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::err::Error;
|
||||
use crate::idx::planner::executor::{
|
||||
KnnBruteForceExpression, KnnBruteForceExpressions, KnnExpressions,
|
||||
|
@ -32,12 +32,11 @@ impl Tree {
|
|||
stk: &mut Stk,
|
||||
ctx: &'a Context<'_>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
table: &'a Table,
|
||||
cond: &'a Option<Cond>,
|
||||
with: &'a Option<With>,
|
||||
) -> Result<Option<Self>, Error> {
|
||||
let mut b = TreeBuilder::new(ctx, opt, txn, table, with);
|
||||
let mut b = TreeBuilder::new(ctx, opt, table, with);
|
||||
if let Some(cond) = cond {
|
||||
let root = b.eval_value(stk, 0, &cond.0).await?;
|
||||
let knn_condition = if b.knn_expressions.is_empty() {
|
||||
|
@ -62,7 +61,6 @@ impl Tree {
|
|||
struct TreeBuilder<'a> {
|
||||
ctx: &'a Context<'a>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
table: &'a Table,
|
||||
with: &'a Option<With>,
|
||||
schemas: HashMap<Table, SchemaCache>,
|
||||
|
@ -90,7 +88,6 @@ impl<'a> TreeBuilder<'a> {
|
|||
fn new(
|
||||
ctx: &'a Context<'_>,
|
||||
opt: &'a Options,
|
||||
txn: &'a Transaction,
|
||||
table: &'a Table,
|
||||
with: &'a Option<With>,
|
||||
) -> Self {
|
||||
|
@ -101,7 +98,6 @@ impl<'a> TreeBuilder<'a> {
|
|||
Self {
|
||||
ctx,
|
||||
opt,
|
||||
txn,
|
||||
table,
|
||||
with,
|
||||
schemas: Default::default(),
|
||||
|
@ -159,7 +155,7 @@ impl<'a> TreeBuilder<'a> {
|
|||
|
||||
async fn compute(&self, stk: &mut Stk, v: &Value, n: Node) -> Result<Node, Error> {
|
||||
Ok(if n == Node::Computable {
|
||||
match v.compute(stk, self.ctx, self.opt, self.txn, None).await {
|
||||
match v.compute(stk, self.ctx, self.opt, None).await {
|
||||
Ok(v) => Node::Computed(Arc::new(v)),
|
||||
Err(_) => Node::Unsupported(format!("Unsupported value: {}", v)),
|
||||
}
|
||||
|
@ -171,7 +167,7 @@ impl<'a> TreeBuilder<'a> {
|
|||
async fn eval_array(&mut self, stk: &mut Stk, a: &Array) -> Result<Node, Error> {
|
||||
let mut values = Vec::with_capacity(a.len());
|
||||
for v in &a.0 {
|
||||
values.push(stk.run(|stk| v.compute(stk, self.ctx, self.opt, self.txn, None)).await?);
|
||||
values.push(stk.run(|stk| v.compute(stk, self.ctx, self.opt, None)).await?);
|
||||
}
|
||||
Ok(Node::Computed(Arc::new(Value::Array(Array::from(values)))))
|
||||
}
|
||||
|
@ -190,7 +186,7 @@ impl<'a> TreeBuilder<'a> {
|
|||
// Compute the idiom value if it is a param
|
||||
if let Some(Part::Start(x)) = i.0.first() {
|
||||
if x.is_param() {
|
||||
let v = stk.run(|stk| i.compute(stk, self.ctx, self.opt, self.txn, None)).await?;
|
||||
let v = stk.run(|stk| i.compute(stk, self.ctx, self.opt, None)).await?;
|
||||
return stk.run(|stk| self.eval_value(stk, group, &v)).await;
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +198,7 @@ impl<'a> TreeBuilder<'a> {
|
|||
}
|
||||
|
||||
async fn resolve_idiom(&mut self, i: &Idiom) -> Result<Node, Error> {
|
||||
let mut tx = self.txn.lock().await;
|
||||
let mut tx = self.ctx.tx_lock().await;
|
||||
self.lazy_load_schema_resolver(&mut tx, self.table).await?;
|
||||
|
||||
// Try to detect if it matches an index
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::dbs;
|
||||
use crate::ctx::Context;
|
||||
use hashbrown::hash_map::Entry;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use reblessive::tree::Stk;
|
||||
|
@ -39,7 +39,7 @@ pub struct MTreeIndex {
|
|||
}
|
||||
|
||||
struct MTreeSearchContext<'a> {
|
||||
txn: &'a dbs::Transaction,
|
||||
ctx: &'a Context<'a>,
|
||||
pt: SharedVector,
|
||||
k: usize,
|
||||
store: &'a MTreeStore,
|
||||
|
@ -109,7 +109,7 @@ impl MTreeIndex {
|
|||
pub async fn knn_search(
|
||||
&self,
|
||||
stk: &mut Stk,
|
||||
txn: &dbs::Transaction,
|
||||
ctx: &Context<'_>,
|
||||
v: &[Number],
|
||||
k: usize,
|
||||
mut chk: MTreeConditionChecker<'_>,
|
||||
|
@ -119,7 +119,7 @@ impl MTreeIndex {
|
|||
vector.check_dimension(self.dim)?;
|
||||
// Build the search context
|
||||
let search = MTreeSearchContext {
|
||||
txn,
|
||||
ctx,
|
||||
pt: vector.into(),
|
||||
k,
|
||||
store: &self.store,
|
||||
|
@ -219,7 +219,7 @@ impl MTree {
|
|||
let mut visited_nodes = HashMap::new();
|
||||
while let Some(e) = queue.pop() {
|
||||
let id = e.id();
|
||||
let node = search.store.get_node_txn(search.txn, id).await?;
|
||||
let node = search.store.get_node_txn(search.ctx, id).await?;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
debug!("Visit node id: {}", id);
|
||||
|
@ -1477,7 +1477,7 @@ mod tests {
|
|||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::dbs;
|
||||
use crate::ctx::Context;
|
||||
use crate::err::Error;
|
||||
use test_log::test;
|
||||
|
||||
|
@ -1498,13 +1498,14 @@ mod tests {
|
|||
t: &MTree,
|
||||
tt: TransactionType,
|
||||
cache_size: usize,
|
||||
) -> (dbs::Transaction, TreeStore<MTreeNode>) {
|
||||
) -> (Context<'a>, TreeStore<MTreeNode>) {
|
||||
let st = ds
|
||||
.index_store()
|
||||
.get_store_mtree(TreeNodeProvider::Debug, t.state.generation, tt, cache_size)
|
||||
.await;
|
||||
let tx = Arc::new(Mutex::new(ds.transaction(tt, Optimistic).await.unwrap()));
|
||||
(tx, st)
|
||||
let ctx = Context::default().set_transaction(tx);
|
||||
(ctx, st)
|
||||
}
|
||||
|
||||
async fn finish_operation(
|
||||
|
@ -1538,8 +1539,8 @@ mod tests {
|
|||
let mut c = 0;
|
||||
for (doc_id, obj) in collection.to_vec_ref() {
|
||||
{
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
t.insert(stk, &mut tx, &mut st, obj.clone(), *doc_id).await?;
|
||||
finish_operation(ds, t, &mut tx, st, true).await?;
|
||||
drop(tx);
|
||||
|
@ -1547,8 +1548,8 @@ mod tests {
|
|||
}
|
||||
c += 1;
|
||||
{
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let p = check_tree_properties(&mut tx, &mut st, t).await?;
|
||||
drop(tx);
|
||||
assert_eq!(p.doc_count, c);
|
||||
|
@ -1566,8 +1567,8 @@ mod tests {
|
|||
) -> Result<HashMap<DocId, SharedVector>, Error> {
|
||||
let mut map = HashMap::with_capacity(collection.len());
|
||||
{
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
for (doc_id, obj) in collection.to_vec_ref() {
|
||||
t.insert(stk, &mut tx, &mut st, obj.clone(), *doc_id).await?;
|
||||
map.insert(*doc_id, obj.clone());
|
||||
|
@ -1576,8 +1577,8 @@ mod tests {
|
|||
drop(tx);
|
||||
}
|
||||
{
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
check_tree_properties(&mut tx, &mut st, t).await?;
|
||||
drop(tx);
|
||||
}
|
||||
|
@ -1596,8 +1597,8 @@ mod tests {
|
|||
for (doc_id, obj) in collection.to_vec_ref() {
|
||||
let deleted = {
|
||||
debug!("### Remove {} {:?}", doc_id, obj);
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Write, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let deleted = t.delete(stk, &mut tx, &mut st, obj.clone(), *doc_id).await?;
|
||||
finish_operation(ds, t, &mut tx, st, true).await?;
|
||||
drop(tx);
|
||||
|
@ -1605,10 +1606,10 @@ mod tests {
|
|||
};
|
||||
all_deleted = all_deleted && deleted;
|
||||
if deleted {
|
||||
let (txn, st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut chk = MTreeConditionChecker::new(&txn);
|
||||
let (ctx, st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut chk = MTreeConditionChecker::new(&ctx);
|
||||
let search = MTreeSearchContext {
|
||||
txn: &txn,
|
||||
ctx: &ctx,
|
||||
pt: obj.clone(),
|
||||
k: 1,
|
||||
store: &st,
|
||||
|
@ -1625,16 +1626,16 @@ mod tests {
|
|||
warn!("Delete failed: {} {:?}", doc_id, obj);
|
||||
}
|
||||
{
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
check_tree_properties(&mut tx, &mut st, t).await?;
|
||||
drop(tx);
|
||||
}
|
||||
}
|
||||
|
||||
if all_deleted {
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
check_tree_properties(&mut tx, &mut st, t).await?.check(0, 0, None, None, 0, 0);
|
||||
drop(tx);
|
||||
}
|
||||
|
@ -1649,13 +1650,13 @@ mod tests {
|
|||
collection: &TestCollection,
|
||||
cache_size: usize,
|
||||
) -> Result<(), Error> {
|
||||
let (txn, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let (ctx, mut st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let max_knn = 20.max(collection.len());
|
||||
for (doc_id, obj) in collection.to_vec_ref() {
|
||||
for knn in 1..max_knn {
|
||||
let mut chk = MTreeConditionChecker::new(&txn);
|
||||
let mut chk = MTreeConditionChecker::new(&ctx);
|
||||
let search = MTreeSearchContext {
|
||||
txn: &txn,
|
||||
ctx: &ctx,
|
||||
pt: obj.clone(),
|
||||
k: knn,
|
||||
store: &st,
|
||||
|
@ -1676,7 +1677,7 @@ mod tests {
|
|||
if expected_len != res.docs.len() {
|
||||
#[cfg(debug_assertions)]
|
||||
debug!("{:?}", res.visited_nodes);
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
check_tree_properties(&mut tx, &mut st, t).await?;
|
||||
drop(tx);
|
||||
}
|
||||
|
@ -1701,11 +1702,11 @@ mod tests {
|
|||
map: &HashMap<DocId, SharedVector>,
|
||||
cache_size: usize,
|
||||
) -> Result<(), Error> {
|
||||
let (txn, st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
let (ctx, st) = new_operation(ds, t, TransactionType::Read, cache_size).await;
|
||||
for obj in map.values() {
|
||||
let mut chk = MTreeConditionChecker::new(&txn);
|
||||
let mut chk = MTreeConditionChecker::new(&ctx);
|
||||
let search = MTreeSearchContext {
|
||||
txn: &txn,
|
||||
ctx: &ctx,
|
||||
pt: obj.clone(),
|
||||
k: map.len(),
|
||||
store: &st,
|
||||
|
@ -1758,8 +1759,8 @@ mod tests {
|
|||
|
||||
let mut t = MTree::new(MState::new(*capacity), distance.clone());
|
||||
|
||||
let (txn, _st) = new_operation(&ds, &t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = txn.lock().await;
|
||||
let (ctx, _st) = new_operation(&ds, &t, TransactionType::Read, cache_size).await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let doc_ids = DocIds::new(
|
||||
ds.index_store(),
|
||||
&mut tx,
|
||||
|
|
|
@ -3,7 +3,7 @@ pub(crate) mod hnsw;
|
|||
mod lru;
|
||||
pub(crate) mod tree;
|
||||
|
||||
use crate::dbs;
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::err::Error;
|
||||
use crate::idx::trees::bkeys::{FstKeys, TrieKeys};
|
||||
|
@ -69,12 +69,12 @@ where
|
|||
|
||||
pub(in crate::idx) async fn get_node_txn(
|
||||
&self,
|
||||
txn: &dbs::Transaction,
|
||||
ctx: &Context<'_>,
|
||||
node_id: NodeId,
|
||||
) -> Result<Arc<StoredNode<N>>, Error> {
|
||||
match self {
|
||||
Self::Read(r) => {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let n = r.get_node(&mut tx, node_id).await;
|
||||
drop(tx);
|
||||
n
|
||||
|
|
|
@ -484,9 +484,9 @@ impl Datastore {
|
|||
info!("Credentials were provided, and no root users were found. The root user '{}' will be created", username);
|
||||
// Create and save a new root users
|
||||
let stm = DefineUserStatement::from((Base::Root, username, password));
|
||||
let ctx = Context::default();
|
||||
let ctx = Context::default().set_transaction(txn.clone());
|
||||
let opt = Options::new().with_auth(Arc::new(Auth::for_root(Role::Owner)));
|
||||
let _ = stm.compute(&ctx, &opt, &txn, None).await?;
|
||||
let _ = stm.compute(&ctx, &opt, None).await?;
|
||||
// We added a new user, so commit the transaction
|
||||
txn.lock().await.commit().await?;
|
||||
// Everything ok
|
||||
|
@ -1260,7 +1260,7 @@ impl Datastore {
|
|||
// Start a new transaction
|
||||
let txn = self.transaction(val.writeable().into(), Optimistic).await?.enclose();
|
||||
// Compute the value
|
||||
let res = stack.enter(|stk| val.compute(stk, &ctx, &opt, &txn, None)).finish().await;
|
||||
let res = stack.enter(|stk| val.compute(stk, &ctx, &opt, None)).finish().await;
|
||||
// Store any data
|
||||
match (res.is_ok(), val.writeable()) {
|
||||
// If the compute was successful, then commit if writeable
|
||||
|
@ -1334,8 +1334,10 @@ impl Datastore {
|
|||
let ctx = vars.attach(ctx)?;
|
||||
// Start a new transaction
|
||||
let txn = self.transaction(val.writeable().into(), Optimistic).await?.enclose();
|
||||
let ctx = ctx.set_transaction(txn.clone());
|
||||
|
||||
// Compute the value
|
||||
let res = stack.enter(|stk| val.compute(stk, &ctx, &opt, &txn, None)).finish().await;
|
||||
let res = stack.enter(|stk| val.compute(stk, &ctx, &opt, None)).finish().await;
|
||||
// Store any data
|
||||
match (res.is_ok(), val.writeable()) {
|
||||
// If the compute was successful, then commit if writeable
|
||||
|
@ -1463,10 +1465,10 @@ mod test {
|
|||
ctx.add_capabilities(dbs.capabilities.clone());
|
||||
// Start a new transaction
|
||||
let txn = dbs.transaction(val.writeable().into(), Optimistic).await?.enclose();
|
||||
let ctx = ctx.set_transaction(txn);
|
||||
// Compute the value
|
||||
let mut stack = reblessive::tree::TreeStack::new();
|
||||
let res =
|
||||
stack.enter(|stk| val.compute(stk, &ctx, &opt, &txn, None)).finish().await.unwrap();
|
||||
let res = stack.enter(|stk| val.compute(stk, &ctx, &opt, None)).finish().await.unwrap();
|
||||
assert_eq!(res, Value::Number(Number::Int(2)));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ mod test_check_lqs_and_send_notifications {
|
|||
use crate::fflags::FFLAGS;
|
||||
use crate::iam::{Auth, Role};
|
||||
use crate::kvs::lq_v2_doc::construct_document;
|
||||
use crate::kvs::{Datastore, LockType, TransactionType};
|
||||
use crate::kvs::Datastore;
|
||||
use crate::sql::paths::{OBJ_PATH_ACCESS, OBJ_PATH_AUTH, OBJ_PATH_TOKEN};
|
||||
use crate::sql::statements::{CreateStatement, DeleteStatement, LiveStatement};
|
||||
use crate::sql::{Fields, Object, Strand, Table, Thing, Uuid, Value, Values};
|
||||
|
@ -217,7 +217,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
const SETUP: Lazy<Arc<TestSuite>> = Lazy::new(|| Arc::new(block_on(setup_test_suite_init())));
|
||||
|
||||
struct TestSuite {
|
||||
ds: Datastore,
|
||||
ns: String,
|
||||
db: String,
|
||||
tb: String,
|
||||
|
@ -249,7 +248,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
.for_each(drop);
|
||||
|
||||
TestSuite {
|
||||
ds,
|
||||
ns: ns.to_string(),
|
||||
db: db.to_string(),
|
||||
tb: tb.to_string(),
|
||||
|
@ -265,12 +263,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
// Setup channels used for listening to LQs
|
||||
let (sender, receiver) = channel::unbounded();
|
||||
let opt = a_usable_options(&sender);
|
||||
let tx = SETUP
|
||||
.ds
|
||||
.transaction(TransactionType::Write, LockType::Optimistic)
|
||||
.await
|
||||
.unwrap()
|
||||
.enclose();
|
||||
|
||||
// WHEN:
|
||||
// Construct document we are validating
|
||||
|
@ -289,7 +281,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
stk,
|
||||
&opt,
|
||||
&Statement::Create(&executed_statement),
|
||||
&tx,
|
||||
&[&live_statement],
|
||||
&sender,
|
||||
)
|
||||
|
@ -309,7 +300,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
notification
|
||||
);
|
||||
assert!(receiver.try_recv().is_err());
|
||||
tx.lock().await.cancel().await.unwrap();
|
||||
}
|
||||
|
||||
#[test_log::test(tokio::test)]
|
||||
|
@ -321,12 +311,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
// Setup channels used for listening to LQs
|
||||
let (sender, receiver) = channel::unbounded();
|
||||
let opt = a_usable_options(&sender);
|
||||
let tx = SETUP
|
||||
.ds
|
||||
.transaction(TransactionType::Write, LockType::Optimistic)
|
||||
.await
|
||||
.unwrap()
|
||||
.enclose();
|
||||
|
||||
// WHEN:
|
||||
// Construct document we are validating
|
||||
|
@ -345,7 +329,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
stk,
|
||||
&opt,
|
||||
&Statement::Delete(&executed_statement),
|
||||
&tx,
|
||||
&[&live_statement],
|
||||
&sender,
|
||||
)
|
||||
|
@ -367,7 +350,6 @@ mod test_check_lqs_and_send_notifications {
|
|||
notification
|
||||
);
|
||||
assert!(receiver.try_recv().is_err());
|
||||
tx.lock().await.cancel().await.unwrap();
|
||||
}
|
||||
|
||||
// Live queries will have authentication info associated with them
|
||||
|
|
|
@ -11,7 +11,6 @@ use crate::kvs::TransactionType::Read;
|
|||
use crate::kvs::{Datastore, Transaction};
|
||||
use crate::sql::statements::show::ShowSince;
|
||||
use crate::vs::conv;
|
||||
use futures::lock::Mutex;
|
||||
use reblessive::tree::Stk;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
@ -56,7 +55,6 @@ pub async fn process_lq_notifications(
|
|||
let lq_pairs = ds.lq_cf_store.read().await.live_queries_for_selector(&selector);
|
||||
|
||||
// Find relevant changes
|
||||
let tx = ds.transaction(Read, Optimistic).await?.enclose();
|
||||
#[cfg(debug_assertions)]
|
||||
trace!("There are {} change sets", change_sets.len());
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -70,8 +68,7 @@ pub async fn process_lq_notifications(
|
|||
.join("\n")
|
||||
);
|
||||
for change_set in change_sets {
|
||||
process_change_set_for_notifications(ds, stk, tx.clone(), opt, change_set, &lq_pairs)
|
||||
.await?;
|
||||
process_change_set_for_notifications(ds, stk, opt, change_set, &lq_pairs).await?;
|
||||
}
|
||||
}
|
||||
trace!("Finished process lq successfully");
|
||||
|
@ -135,7 +132,6 @@ async fn populate_relevant_changesets(
|
|||
async fn process_change_set_for_notifications(
|
||||
ds: &Datastore,
|
||||
stk: &mut Stk,
|
||||
tx: Arc<Mutex<Transaction>>,
|
||||
opt: &Options,
|
||||
change_set: ChangeSet,
|
||||
lq_pairs: &[(LqIndexKey, LqIndexValue)],
|
||||
|
@ -171,7 +167,6 @@ async fn process_change_set_for_notifications(
|
|||
stk,
|
||||
opt,
|
||||
&Statement::Live(&lq_value.stm),
|
||||
&tx,
|
||||
[&lq_value.stm].as_slice(),
|
||||
&local_notification_channel_sender,
|
||||
)
|
||||
|
|
|
@ -106,9 +106,10 @@ async fn expired_nodes_get_live_queries_archived() {
|
|||
.with_id(old_node);
|
||||
let opt = Options::new_with_sender(&opt, sender);
|
||||
let tx = Arc::new(Mutex::new(test.db.transaction(Write, Optimistic).await.unwrap()));
|
||||
let ctx = ctx.set_transaction(tx);
|
||||
let res = {
|
||||
let mut stack = reblessive::tree::TreeStack::new();
|
||||
stack.enter(|stk| lq.compute(stk, &ctx, &opt, &tx, None)).finish().await.unwrap()
|
||||
stack.enter(|stk| lq.compute(stk, &ctx, &opt, None)).finish().await.unwrap()
|
||||
};
|
||||
match res {
|
||||
Value::Uuid(_) => {}
|
||||
|
@ -116,7 +117,7 @@ async fn expired_nodes_get_live_queries_archived() {
|
|||
panic!("Not a uuid: {:?}", res);
|
||||
}
|
||||
}
|
||||
tx.lock().await.commit().await.unwrap();
|
||||
ctx.tx_lock().await.commit().await.unwrap();
|
||||
|
||||
// Set up second node at a later timestamp
|
||||
let new_node = Uuid::parse_str("04da7d4c-0086-4358-8318-49f0bb168fa7").unwrap();
|
||||
|
@ -170,6 +171,7 @@ async fn single_live_queries_are_garbage_collected() {
|
|||
// We set up 2 live queries, one of which we want to garbage collect
|
||||
trace!("Setting up live queries");
|
||||
let tx = Arc::new(Mutex::new(test.db.transaction(Write, Optimistic).await.unwrap()));
|
||||
let ctx = ctx.set_transaction(tx);
|
||||
let live_query_to_delete = Uuid::parse_str("8aed07c4-9683-480e-b1e4-f0db8b331530").unwrap();
|
||||
let live_st = LiveStatement {
|
||||
id: sql::Uuid(live_query_to_delete),
|
||||
|
@ -183,7 +185,7 @@ async fn single_live_queries_are_garbage_collected() {
|
|||
auth: Some(Auth::for_root(Role::Owner)),
|
||||
};
|
||||
stack
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, &tx, None))
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, None))
|
||||
.finish()
|
||||
.await
|
||||
.map_err(|e| format!("Error computing live statement: {:?} {:?}", live_st, e))
|
||||
|
@ -201,12 +203,12 @@ async fn single_live_queries_are_garbage_collected() {
|
|||
auth: Some(Auth::for_root(Role::Owner)),
|
||||
};
|
||||
stack
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, &tx, None))
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, None))
|
||||
.finish()
|
||||
.await
|
||||
.map_err(|e| format!("Error computing live statement: {:?} {:?}", live_st, e))
|
||||
.unwrap();
|
||||
tx.lock().await.commit().await.unwrap();
|
||||
ctx.tx_lock().await.commit().await.unwrap();
|
||||
|
||||
// Subject: Perform the action we are testing
|
||||
trace!("Garbage collecting dead sessions");
|
||||
|
@ -260,6 +262,7 @@ async fn bootstrap_does_not_error_on_missing_live_queries() {
|
|||
// We set up 2 live queries, one of which we want to garbage collect
|
||||
trace!("Setting up live queries");
|
||||
let tx = Arc::new(Mutex::new(test.db.transaction(Write, Optimistic).await.unwrap()));
|
||||
let ctx = ctx.set_transaction(tx);
|
||||
let live_query_to_corrupt = Uuid::parse_str("d4cee7ce-5c78-4a30-9fa9-2444d58029f6").unwrap();
|
||||
let live_st = LiveStatement {
|
||||
id: sql::Uuid(live_query_to_corrupt),
|
||||
|
@ -273,7 +276,7 @@ async fn bootstrap_does_not_error_on_missing_live_queries() {
|
|||
auth: Some(Auth::for_root(Role::Owner)),
|
||||
};
|
||||
stack
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, &tx, None))
|
||||
.enter(|stk| live_st.compute(stk, &ctx, &options, None))
|
||||
.finish()
|
||||
.await
|
||||
.map_err(|e| format!("Error computing live statement: {:?} {:?}", live_st, e))
|
||||
|
@ -281,8 +284,8 @@ async fn bootstrap_does_not_error_on_missing_live_queries() {
|
|||
|
||||
// Now we corrupt the live query entry by leaving the node entry in but removing the table entry
|
||||
let key = crate::key::table::lq::new(namespace, database, table, live_query_to_corrupt);
|
||||
tx.lock().await.del(key).await.unwrap();
|
||||
tx.lock().await.commit().await.unwrap();
|
||||
ctx.tx_lock().await.del(key).await.unwrap();
|
||||
ctx.tx_lock().await.commit().await.unwrap();
|
||||
|
||||
// Subject: Perform the action we are testing
|
||||
trace!("Bootstrapping");
|
||||
|
|
|
@ -28,6 +28,7 @@ use crate::dbs::node::ClusterMembership;
|
|||
use crate::dbs::node::Timestamp;
|
||||
use crate::err::Error;
|
||||
use crate::idg::u32::U32;
|
||||
#[cfg(debug_assertions)]
|
||||
use crate::key::debug::sprint_key;
|
||||
use crate::key::error::KeyCategory;
|
||||
use crate::key::key_req::KeyRequirements;
|
||||
|
|
|
@ -5,7 +5,8 @@ extern crate tracing;
|
|||
mod mac;
|
||||
|
||||
mod cf;
|
||||
mod ctx;
|
||||
#[doc(hidden)]
|
||||
pub mod ctx;
|
||||
mod doc;
|
||||
mod exe;
|
||||
mod fnc;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{
|
||||
|
@ -137,12 +137,11 @@ impl Array {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
let mut x = Self::with_capacity(self.len());
|
||||
for v in self.iter() {
|
||||
match v.compute(stk, ctx, opt, txn, doc).await {
|
||||
match v.compute(stk, ctx, opt, doc).await {
|
||||
Ok(v) => x.push(v),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::fmt::{is_pretty, pretty_indent, Fmt, Pretty};
|
||||
|
@ -51,7 +51,6 @@ impl Block {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Duplicate context
|
||||
|
@ -60,65 +59,65 @@ impl Block {
|
|||
for (i, v) in self.iter().enumerate() {
|
||||
match v {
|
||||
Entry::Set(v) => {
|
||||
let val = v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
let val = v.compute(stk, &ctx, opt, doc).await?;
|
||||
ctx.add_value(v.name.to_owned(), val);
|
||||
}
|
||||
Entry::Throw(v) => {
|
||||
// Always errors immediately
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Break(v) => {
|
||||
// Always errors immediately
|
||||
v.compute(&ctx, opt, txn, doc).await?;
|
||||
v.compute(&ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Continue(v) => {
|
||||
// Always errors immediately
|
||||
v.compute(&ctx, opt, txn, doc).await?;
|
||||
v.compute(&ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Foreach(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Ifelse(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Select(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Create(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Update(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Delete(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Relate(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Insert(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Define(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Rebuild(v) => {
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Remove(v) => {
|
||||
v.compute(&ctx, opt, txn, doc).await?;
|
||||
v.compute(&ctx, opt, doc).await?;
|
||||
}
|
||||
Entry::Output(v) => {
|
||||
// Return the RETURN value
|
||||
return v.compute(stk, &ctx, opt, txn, doc).await;
|
||||
return v.compute(stk, &ctx, opt, doc).await;
|
||||
}
|
||||
Entry::Value(v) => {
|
||||
if i == self.len() - 1 {
|
||||
// If the last entry then return the value
|
||||
return v.compute(stk, &ctx, opt, txn, doc).await;
|
||||
return v.compute(stk, &ctx, opt, doc).await;
|
||||
} else {
|
||||
// Otherwise just process the value
|
||||
v.compute(stk, &ctx, opt, txn, doc).await?;
|
||||
v.compute(stk, &ctx, opt, doc).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{Idiom, Kind, Value};
|
||||
|
@ -39,11 +39,10 @@ impl Cast {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Compute the value to be cast and convert it
|
||||
stk.run(|stk| self.1.compute(stk, ctx, opt, txn, doc)).await?.convert_to(&self.0)
|
||||
stk.run(|stk| self.1.compute(stk, ctx, opt, doc)).await?.convert_to(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -81,7 +81,6 @@ impl Constant {
|
|||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
Ok(match self.value() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::err::Error;
|
||||
use crate::sql::fmt::Fmt;
|
||||
use crate::sql::idiom::Idiom;
|
||||
|
@ -40,28 +40,27 @@ impl Data {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
) -> Result<Option<Value>, Error> {
|
||||
match self {
|
||||
Self::MergeExpression(v) => match v {
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, None).await?.rid().some()),
|
||||
Value::Object(_) => Ok(v.rid().some()),
|
||||
_ => Ok(None),
|
||||
},
|
||||
Self::ReplaceExpression(v) => match v {
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, None).await?.rid().some()),
|
||||
Value::Object(_) => Ok(v.rid().some()),
|
||||
_ => Ok(None),
|
||||
},
|
||||
Self::ContentExpression(v) => match v {
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, txn, None).await?.rid().some()),
|
||||
Value::Param(v) => Ok(v.compute(stk, ctx, opt, None).await?.rid().some()),
|
||||
Value::Object(_) => Ok(v.rid().some()),
|
||||
_ => Ok(None),
|
||||
},
|
||||
Self::SetExpression(v) => match v.iter().find(|f| f.0.is_id()) {
|
||||
Some((_, _, v)) => {
|
||||
// This SET expression has an 'id' field
|
||||
Ok(v.compute(stk, ctx, opt, txn, None).await?.some())
|
||||
Ok(v.compute(stk, ctx, opt, None).await?.some())
|
||||
}
|
||||
// This SET expression had no 'id' field
|
||||
_ => Ok(None),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::fnc;
|
||||
|
@ -102,7 +102,6 @@ impl Expression {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
let (l, o, r) = match self {
|
||||
|
@ -110,7 +109,7 @@ impl Expression {
|
|||
o,
|
||||
v,
|
||||
} => {
|
||||
let operand = v.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let operand = v.compute(stk, ctx, opt, doc).await?;
|
||||
return match o {
|
||||
Operator::Neg => fnc::operate::neg(operand),
|
||||
// TODO: Check if it is a number?
|
||||
|
@ -126,7 +125,7 @@ impl Expression {
|
|||
} => (l, o, r),
|
||||
};
|
||||
|
||||
let l = l.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let l = l.compute(stk, ctx, opt, doc).await?;
|
||||
match o {
|
||||
Operator::Or => {
|
||||
if l.is_truthy() {
|
||||
|
@ -150,7 +149,7 @@ impl Expression {
|
|||
}
|
||||
_ => {} // Continue
|
||||
}
|
||||
let r = r.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let r = r.compute(stk, ctx, opt, doc).await?;
|
||||
match o {
|
||||
Operator::Or => fnc::operate::or(l, r),
|
||||
Operator::And => fnc::operate::and(l, r),
|
||||
|
@ -187,11 +186,9 @@ impl Expression {
|
|||
Operator::NoneInside => fnc::operate::inside_none(&l, &r),
|
||||
Operator::Outside => fnc::operate::outside(&l, &r),
|
||||
Operator::Intersects => fnc::operate::intersects(&l, &r),
|
||||
Operator::Matches(_) => {
|
||||
fnc::operate::matches(stk, ctx, opt, txn, doc, self, l, r).await
|
||||
}
|
||||
Operator::Matches(_) => fnc::operate::matches(stk, ctx, opt, doc, self, l, r).await,
|
||||
Operator::Knn(_, _) | Operator::Ann(_, _) => {
|
||||
fnc::operate::knn(stk, ctx, opt, txn, doc, self).await
|
||||
fnc::operate::knn(stk, ctx, opt, doc, self).await
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::statements::info::InfoStructure;
|
||||
|
@ -79,15 +79,14 @@ impl Fields {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
group: bool,
|
||||
) -> Result<Value, Error> {
|
||||
if let Some(doc) = doc {
|
||||
self.compute_value(stk, ctx, opt, txn, doc, group).await
|
||||
self.compute_value(stk, ctx, opt, doc, group).await
|
||||
} else {
|
||||
let doc = (&Value::None).into();
|
||||
self.compute_value(stk, ctx, opt, txn, &doc, group).await
|
||||
self.compute_value(stk, ctx, opt, &doc, group).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +95,6 @@ impl Fields {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: &CursorDoc<'_>,
|
||||
group: bool,
|
||||
) -> Result<Value, Error> {
|
||||
|
@ -104,7 +102,7 @@ impl Fields {
|
|||
let opt = &opt.new_with_futures(true);
|
||||
// Process the desired output
|
||||
let mut out = match self.is_all() {
|
||||
true => doc.doc.compute(stk, ctx, opt, txn, Some(doc)).await?,
|
||||
true => doc.doc.compute(stk, ctx, opt, Some(doc)).await?,
|
||||
false => Value::base(),
|
||||
};
|
||||
for v in self.other() {
|
||||
|
@ -123,13 +121,13 @@ impl Fields {
|
|||
Value::Function(f) if group && f.is_aggregate() => {
|
||||
let x = match f.args().len() {
|
||||
// If no function arguments, then compute the result
|
||||
0 => f.compute(stk, ctx, opt, txn, Some(doc)).await?,
|
||||
0 => f.compute(stk, ctx, opt, Some(doc)).await?,
|
||||
// If arguments, then pass the first value through
|
||||
_ => f.args()[0].compute(stk, ctx, opt, txn, Some(doc)).await?,
|
||||
_ => f.args()[0].compute(stk, ctx, opt, Some(doc)).await?,
|
||||
};
|
||||
// Check if this is a single VALUE field expression
|
||||
match self.single().is_some() {
|
||||
false => out.set(stk, ctx, opt, txn, name.as_ref(), x).await?,
|
||||
false => out.set(stk, ctx, opt, name.as_ref(), x).await?,
|
||||
true => out = x,
|
||||
}
|
||||
}
|
||||
|
@ -146,9 +144,9 @@ impl Fields {
|
|||
};
|
||||
// Continue fetching the next idiom part
|
||||
let x = x
|
||||
.get(stk, ctx, opt, txn, Some(doc), v)
|
||||
.get(stk, ctx, opt, Some(doc), v)
|
||||
.await?
|
||||
.compute(stk, ctx, opt, txn, Some(doc))
|
||||
.compute(stk, ctx, opt, Some(doc))
|
||||
.await?
|
||||
.flatten();
|
||||
// Add the result to the temporary store
|
||||
|
@ -160,13 +158,13 @@ impl Fields {
|
|||
// This is an alias expression part
|
||||
Some(a) => {
|
||||
if let Some(i) = alias {
|
||||
out.set(stk, ctx, opt, txn, i, x.clone()).await?;
|
||||
out.set(stk, ctx, opt, i, x.clone()).await?;
|
||||
}
|
||||
out.set(stk, ctx, opt, txn, a, x).await?;
|
||||
out.set(stk, ctx, opt, a, x).await?;
|
||||
}
|
||||
// This is the end of the expression
|
||||
None => {
|
||||
out.set(stk, ctx, opt, txn, alias.as_ref().unwrap_or(v), x)
|
||||
out.set(stk, ctx, opt, alias.as_ref().unwrap_or(v), x)
|
||||
.await?
|
||||
}
|
||||
}
|
||||
|
@ -175,14 +173,14 @@ impl Fields {
|
|||
// This expression is a variable fields expression
|
||||
Value::Function(f) if f.name() == Some("type::fields") => {
|
||||
// Process the function using variable field projections
|
||||
let expr = expr.compute(stk, ctx, opt, txn, Some(doc)).await?;
|
||||
let expr = expr.compute(stk, ctx, opt, Some(doc)).await?;
|
||||
// Check if this is a single VALUE field expression
|
||||
match self.single().is_some() {
|
||||
false => {
|
||||
// Get the first argument which is guaranteed to exist
|
||||
let args = match f.args().first().unwrap() {
|
||||
Value::Param(v) => {
|
||||
v.compute(stk, ctx, opt, txn, Some(doc)).await?
|
||||
v.compute(stk, ctx, opt, Some(doc)).await?
|
||||
}
|
||||
v => v.to_owned(),
|
||||
};
|
||||
|
@ -195,7 +193,7 @@ impl Fields {
|
|||
// This value is always a string, so we can convert it
|
||||
let name = syn::idiom(&name.to_raw_string())?;
|
||||
// Check if this is a single VALUE field expression
|
||||
out.set(stk, ctx, opt, txn, name.as_ref(), expr).await?
|
||||
out.set(stk, ctx, opt, name.as_ref(), expr).await?
|
||||
}
|
||||
}
|
||||
true => out = expr,
|
||||
|
@ -204,14 +202,14 @@ impl Fields {
|
|||
// This expression is a variable field expression
|
||||
Value::Function(f) if f.name() == Some("type::field") => {
|
||||
// Process the function using variable field projections
|
||||
let expr = expr.compute(stk, ctx, opt, txn, Some(doc)).await?;
|
||||
let expr = expr.compute(stk, ctx, opt, Some(doc)).await?;
|
||||
// Check if this is a single VALUE field expression
|
||||
match self.single().is_some() {
|
||||
false => {
|
||||
// Get the first argument which is guaranteed to exist
|
||||
let name = match f.args().first().unwrap() {
|
||||
Value::Param(v) => {
|
||||
v.compute(stk, ctx, opt, txn, Some(doc)).await?
|
||||
v.compute(stk, ctx, opt, Some(doc)).await?
|
||||
}
|
||||
v => v.to_owned(),
|
||||
};
|
||||
|
@ -223,17 +221,17 @@ impl Fields {
|
|||
Cow::Owned(syn::idiom(&name.to_raw_string())?)
|
||||
};
|
||||
// Add the projected field to the output document
|
||||
out.set(stk, ctx, opt, txn, name.as_ref(), expr).await?
|
||||
out.set(stk, ctx, opt, name.as_ref(), expr).await?
|
||||
}
|
||||
true => out = expr,
|
||||
}
|
||||
}
|
||||
// This expression is a normal field expression
|
||||
_ => {
|
||||
let expr = expr.compute(stk, ctx, opt, txn, Some(doc)).await?;
|
||||
let expr = expr.compute(stk, ctx, opt, Some(doc)).await?;
|
||||
// Check if this is a single VALUE field expression
|
||||
match self.single().is_some() {
|
||||
false => out.set(stk, ctx, opt, txn, name.as_ref(), expr).await?,
|
||||
false => out.set(stk, ctx, opt, name.as_ref(), expr).await?,
|
||||
true => out = expr,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::fnc;
|
||||
|
@ -184,7 +184,6 @@ impl Function {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Ensure futures are run
|
||||
|
@ -198,12 +197,12 @@ impl Function {
|
|||
let a = stk
|
||||
.scope(|scope| {
|
||||
try_join_all(
|
||||
x.iter().map(|v| scope.run(|stk| v.compute(stk, ctx, opt, txn, doc))),
|
||||
x.iter().map(|v| scope.run(|stk| v.compute(stk, ctx, opt, doc))),
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
// Run the normal function
|
||||
fnc::run(stk, ctx, opt, txn, doc, s, a).await
|
||||
fnc::run(stk, ctx, opt, doc, s, a).await
|
||||
}
|
||||
Self::Custom(s, x) => {
|
||||
// Check that a database is set to prevent a panic
|
||||
|
@ -215,9 +214,11 @@ impl Function {
|
|||
// Get the function definition
|
||||
let val = {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the function definition
|
||||
run.get_and_cache_db_function(opt.ns(), opt.db(), s).await?
|
||||
let val = run.get_and_cache_db_function(opt.ns(), opt.db(), s).await?;
|
||||
drop(run);
|
||||
val
|
||||
};
|
||||
// Check permissions
|
||||
if opt.check_perms(Action::View) {
|
||||
|
@ -232,8 +233,7 @@ impl Function {
|
|||
// Disable permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
// Process the PERMISSION clause
|
||||
if !stk.run(|stk| e.compute(stk, ctx, opt, txn, doc)).await?.is_truthy()
|
||||
{
|
||||
if !stk.run(|stk| e.compute(stk, ctx, opt, doc)).await?.is_truthy() {
|
||||
return Err(Error::FunctionPermissions {
|
||||
name: s.to_owned(),
|
||||
});
|
||||
|
@ -265,7 +265,7 @@ impl Function {
|
|||
let a = stk
|
||||
.scope(|scope| {
|
||||
try_join_all(
|
||||
x.iter().map(|v| scope.run(|stk| v.compute(stk, ctx, opt, txn, doc))),
|
||||
x.iter().map(|v| scope.run(|stk| v.compute(stk, ctx, opt, doc))),
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
|
@ -276,7 +276,7 @@ impl Function {
|
|||
ctx.add_value(name.to_raw(), val.coerce_to(kind)?);
|
||||
}
|
||||
// Run the custom function
|
||||
stk.run(|stk| val.block.compute(stk, &ctx, opt, txn, doc)).await
|
||||
stk.run(|stk| val.block.compute(stk, &ctx, opt, doc)).await
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
Self::Script(s, x) => {
|
||||
|
@ -288,13 +288,12 @@ impl Function {
|
|||
let a = stk
|
||||
.scope(|scope| {
|
||||
try_join_all(
|
||||
x.iter()
|
||||
.map(|v| scope.run(|stk| v.compute(stk, ctx, opt, txn, doc))),
|
||||
x.iter().map(|v| scope.run(|stk| v.compute(stk, ctx, opt, doc))),
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
// Run the script function
|
||||
fnc::script::run(ctx, opt, txn, doc, s, a).await
|
||||
fnc::script::run(ctx, opt, doc, s, a).await
|
||||
}
|
||||
#[cfg(not(feature = "scripting"))]
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::block::Block;
|
||||
|
@ -31,12 +31,11 @@ impl Future {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Process the future if enabled
|
||||
match opt.futures {
|
||||
true => stk.run(|stk| self.0.compute(stk, ctx, opt, txn, doc)).await?.ok(),
|
||||
true => stk.run(|stk| self.0.compute(stk, ctx, opt, doc)).await?.ok(),
|
||||
false => Ok(self.clone().into()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::cnf::ID_CHARS;
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{escape::escape_rid, Array, Number, Object, Strand, Thing, Uuid, Value};
|
||||
|
@ -186,17 +186,16 @@ impl Id {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Id, Error> {
|
||||
match self {
|
||||
Id::Number(v) => Ok(Id::Number(*v)),
|
||||
Id::String(v) => Ok(Id::String(v.clone())),
|
||||
Id::Array(v) => match v.compute(stk, ctx, opt, txn, doc).await? {
|
||||
Id::Array(v) => match v.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Array(v) => Ok(Id::Array(v)),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Id::Object(v) => match v.compute(stk, ctx, opt, txn, doc).await? {
|
||||
Id::Object(v) => match v.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Object(v) => Ok(Id::Object(v)),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::statements::info::InfoStructure;
|
||||
|
@ -160,28 +160,23 @@ impl Idiom {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
match self.first() {
|
||||
// The starting part is a value
|
||||
Some(Part::Start(v)) => {
|
||||
v.compute(stk, ctx, opt, txn, doc)
|
||||
v.compute(stk, ctx, opt, doc)
|
||||
.await?
|
||||
.get(stk, ctx, opt, txn, doc, self.as_ref().next())
|
||||
.get(stk, ctx, opt, doc, self.as_ref().next())
|
||||
.await?
|
||||
.compute(stk, ctx, opt, txn, doc)
|
||||
.compute(stk, ctx, opt, doc)
|
||||
.await
|
||||
}
|
||||
// Otherwise use the current document
|
||||
_ => match doc {
|
||||
// There is a current document
|
||||
Some(v) => {
|
||||
v.doc
|
||||
.get(stk, ctx, opt, txn, doc, self)
|
||||
.await?
|
||||
.compute(stk, ctx, opt, txn, doc)
|
||||
.await
|
||||
v.doc.get(stk, ctx, opt, doc, self).await?.compute(stk, ctx, opt, doc).await
|
||||
}
|
||||
// There isn't any document
|
||||
None => Ok(Value::None),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::number::Number;
|
||||
|
@ -21,10 +21,9 @@ impl Limit {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<usize, Error> {
|
||||
match self.0.compute(stk, ctx, opt, txn, doc).await {
|
||||
match self.0.compute(stk, ctx, opt, doc).await {
|
||||
// This is a valid limiting number
|
||||
Ok(Value::Number(Number::Int(v))) if v >= 0 => Ok(v as usize),
|
||||
// An invalid value was specified
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -57,7 +57,6 @@ impl Model {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Ensure futures are run
|
||||
|
@ -69,9 +68,12 @@ impl Model {
|
|||
// Get the model definition
|
||||
let val = {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the function definition
|
||||
run.get_and_cache_db_model(opt.ns(), opt.db(), &self.name, &self.version).await?
|
||||
let val =
|
||||
run.get_and_cache_db_model(opt.ns(), opt.db(), &self.name, &self.version).await?;
|
||||
drop(run);
|
||||
val
|
||||
};
|
||||
// Calculate the model path
|
||||
let path = format!(
|
||||
|
@ -95,7 +97,7 @@ impl Model {
|
|||
// Disable permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
// Process the PERMISSION clause
|
||||
if !stk.run(|stk| e.compute(stk, ctx, opt, txn, doc)).await?.is_truthy() {
|
||||
if !stk.run(|stk| e.compute(stk, ctx, opt, doc)).await?.is_truthy() {
|
||||
return Err(Error::FunctionPermissions {
|
||||
name: self.name.to_owned(),
|
||||
});
|
||||
|
@ -106,9 +108,7 @@ impl Model {
|
|||
// Compute the function arguments
|
||||
let mut args = stk
|
||||
.scope(|stk| {
|
||||
try_join_all(
|
||||
self.args.iter().map(|v| stk.run(|stk| v.compute(stk, ctx, opt, txn, doc))),
|
||||
)
|
||||
try_join_all(self.args.iter().map(|v| stk.run(|stk| v.compute(stk, ctx, opt, doc))))
|
||||
})
|
||||
.await?;
|
||||
// Check the minimum argument length
|
||||
|
@ -224,7 +224,6 @@ impl Model {
|
|||
_stk: &mut Stk,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
Err(Error::InvalidModel {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{
|
||||
|
@ -220,12 +220,11 @@ impl Object {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
let mut x = BTreeMap::new();
|
||||
for (k, v) in self.iter() {
|
||||
match v.compute(stk, ctx, opt, txn, doc).await {
|
||||
match v.compute(stk, ctx, opt, doc).await {
|
||||
Ok(v) => x.insert(k.clone(), v),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
ctx::Context,
|
||||
dbs::{Options, Transaction},
|
||||
dbs::Options,
|
||||
doc::CursorDoc,
|
||||
err::Error,
|
||||
iam::Action,
|
||||
|
@ -52,7 +52,6 @@ impl Param {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Find the variable by name
|
||||
|
@ -60,21 +59,21 @@ impl Param {
|
|||
// This is a special param
|
||||
"this" | "self" => match doc {
|
||||
// The base document exists
|
||||
Some(v) => v.doc.compute(stk, ctx, opt, txn, doc).await,
|
||||
Some(v) => v.doc.compute(stk, ctx, opt, doc).await,
|
||||
// The base document does not exist
|
||||
None => Ok(Value::None),
|
||||
},
|
||||
// This is a normal param
|
||||
v => match ctx.value(v) {
|
||||
// The param has been set locally
|
||||
Some(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Some(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
// The param has not been set locally
|
||||
None => {
|
||||
// Check that a database is set to prevent a panic
|
||||
opt.valid_for_db()?;
|
||||
let val = {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Get the param definition
|
||||
run.get_and_cache_db_param(opt.ns(), opt.db(), v).await
|
||||
};
|
||||
|
@ -95,7 +94,7 @@ impl Param {
|
|||
// Disable permissions
|
||||
let opt = &opt.new_with_perms(false);
|
||||
// Process the PERMISSION clause
|
||||
if !e.compute(stk, ctx, opt, txn, doc).await?.is_truthy() {
|
||||
if !e.compute(stk, ctx, opt, doc).await?.is_truthy() {
|
||||
return Err(Error::ParamPermissions {
|
||||
name: v.to_owned(),
|
||||
});
|
||||
|
@ -104,7 +103,7 @@ impl Param {
|
|||
}
|
||||
}
|
||||
// Return the computed value
|
||||
val.value.compute(stk, ctx, opt, txn, doc).await
|
||||
val.value.compute(stk, ctx, opt, doc).await
|
||||
}
|
||||
// The param has not been set globally
|
||||
Err(_) => Ok(Value::None),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::Cond;
|
||||
|
@ -162,19 +162,18 @@ impl Range {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
Ok(Value::Range(Box::new(Range {
|
||||
tb: self.tb.clone(),
|
||||
beg: match &self.beg {
|
||||
Bound::Included(id) => Bound::Included(id.compute(stk, ctx, opt, txn, doc).await?),
|
||||
Bound::Excluded(id) => Bound::Excluded(id.compute(stk, ctx, opt, txn, doc).await?),
|
||||
Bound::Included(id) => Bound::Included(id.compute(stk, ctx, opt, doc).await?),
|
||||
Bound::Excluded(id) => Bound::Excluded(id.compute(stk, ctx, opt, doc).await?),
|
||||
Bound::Unbounded => Bound::Unbounded,
|
||||
},
|
||||
end: match &self.end {
|
||||
Bound::Included(id) => Bound::Included(id.compute(stk, ctx, opt, txn, doc).await?),
|
||||
Bound::Excluded(id) => Bound::Excluded(id.compute(stk, ctx, opt, txn, doc).await?),
|
||||
Bound::Included(id) => Bound::Included(id.compute(stk, ctx, opt, doc).await?),
|
||||
Bound::Excluded(id) => Bound::Excluded(id.compute(stk, ctx, opt, doc).await?),
|
||||
Bound::Unbounded => Bound::Unbounded,
|
||||
},
|
||||
})))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::number::Number;
|
||||
|
@ -21,10 +21,9 @@ impl Start {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<usize, Error> {
|
||||
match self.0.compute(stk, ctx, opt, txn, doc).await {
|
||||
match self.0.compute(stk, ctx, opt, doc).await {
|
||||
// This is a valid starting number
|
||||
Ok(Value::Number(Number::Int(v))) if v >= 0 => Ok(v as usize),
|
||||
// An invalid value was specified
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::statements::rebuild::RebuildStatement;
|
||||
|
@ -140,37 +140,36 @@ impl Statement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Self::Analyze(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Break(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Continue(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Create(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Delete(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Define(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Foreach(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Ifelse(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Info(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Insert(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Kill(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Live(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Output(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Relate(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Rebuild(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Remove(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Select(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Set(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Show(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Sleep(v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Throw(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Update(v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Analyze(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Break(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Continue(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Create(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Delete(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Define(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Foreach(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Ifelse(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Info(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Insert(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Kill(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Live(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Output(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Relate(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Rebuild(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Remove(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Select(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Set(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Show(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Sleep(v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Throw(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Update(v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Value(v) => {
|
||||
// Ensure futures are processed
|
||||
let opt = &opt.new_with_futures(true);
|
||||
// Process the output value
|
||||
v.compute(stk, ctx, opt, txn, doc).await
|
||||
v.compute(stk, ctx, opt, doc).await
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -32,7 +31,6 @@ impl AnalyzeStatement {
|
|||
&self,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
|
@ -40,8 +38,8 @@ impl AnalyzeStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Index, &Base::Db)?;
|
||||
// Read the index
|
||||
let ix = txn
|
||||
.lock()
|
||||
let ix = ctx
|
||||
.tx_lock()
|
||||
.await
|
||||
.get_and_cache_tb_index(opt.ns(), opt.db(), tb.as_str(), idx.as_str())
|
||||
.await?;
|
||||
|
@ -50,20 +48,13 @@ impl AnalyzeStatement {
|
|||
// Index operation dispatching
|
||||
let value: Value = match &ix.index {
|
||||
Index::Search(p) => {
|
||||
let ft = FtIndex::new(
|
||||
ctx.get_index_stores(),
|
||||
opt,
|
||||
txn,
|
||||
p.az.as_str(),
|
||||
ikb,
|
||||
p,
|
||||
TransactionType::Read,
|
||||
)
|
||||
.await?;
|
||||
ft.statistics(txn).await?.into()
|
||||
let ft =
|
||||
FtIndex::new(ctx, opt, p.az.as_str(), ikb, p, TransactionType::Read)
|
||||
.await?;
|
||||
ft.statistics(ctx).await?.into()
|
||||
}
|
||||
Index::MTree(p) => {
|
||||
let mut tx = txn.lock().await;
|
||||
let mut tx = ctx.tx_lock().await;
|
||||
let mt = MTreeIndex::new(
|
||||
ctx.get_index_stores(),
|
||||
&mut tx,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -24,7 +24,6 @@ impl BreakStatement {
|
|||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
Err(Error::Break)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::Value;
|
||||
|
@ -24,7 +24,6 @@ impl ContinueStatement {
|
|||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
_opt: &Options,
|
||||
_txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
Err(Error::Continue)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Iterator, Options, Statement, Transaction};
|
||||
use crate::dbs::{Iterator, Options, Statement};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{Data, Output, Timeout, Value, Values};
|
||||
|
@ -40,7 +40,6 @@ impl CreateStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Valid options?
|
||||
|
@ -53,8 +52,8 @@ impl CreateStatement {
|
|||
let opt = &opt.new_with_futures(false);
|
||||
// Loop over the create targets
|
||||
for w in self.what.0.iter() {
|
||||
let v = w.compute(stk, ctx, opt, txn, doc).await?;
|
||||
i.prepare(stk, ctx, opt, txn, &stm, v).await.map_err(|e| match e {
|
||||
let v = w.compute(stk, ctx, opt, doc).await?;
|
||||
i.prepare(stk, ctx, opt, &stm, v).await.map_err(|e| match e {
|
||||
Error::InvalidStatementTarget {
|
||||
value: v,
|
||||
} => Error::CreateStatement {
|
||||
|
@ -64,7 +63,7 @@ impl CreateStatement {
|
|||
})?;
|
||||
}
|
||||
// Output the results
|
||||
match i.output(stk, ctx, opt, txn, &stm).await? {
|
||||
match i.output(stk, ctx, opt, &stm).await? {
|
||||
// This is a single record result
|
||||
Value::Array(mut a) if self.only => match a.len() {
|
||||
// There was exactly one result
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -38,9 +38,8 @@ impl DefineAccessStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Actor, &self.base)?;
|
||||
|
@ -48,7 +47,7 @@ impl DefineAccessStatement {
|
|||
match &self.base {
|
||||
Base::Ns => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if access method already exists
|
||||
|
@ -73,7 +72,7 @@ impl DefineAccessStatement {
|
|||
}
|
||||
Base::Db => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if access method already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -28,15 +28,14 @@ pub struct DefineAnalyzerStatement {
|
|||
impl DefineAnalyzerStatement {
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Analyzer, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if analyzer already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -27,15 +27,14 @@ impl DefineDatabaseStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Database, &Base::Ns)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if database already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -28,15 +28,14 @@ impl DefineEventStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Event, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if event already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -39,15 +39,14 @@ impl DefineFieldStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Field, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if field already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -31,15 +31,14 @@ impl DefineFunctionStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Function, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if function already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Force, Options, Transaction};
|
||||
use crate::dbs::{Force, Options};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -35,13 +35,12 @@ impl DefineIndexStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Index, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if index already exists
|
||||
|
@ -104,7 +103,7 @@ impl DefineIndexStatement {
|
|||
what: Values(vec![Value::Table(self.what.clone().into())]),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
stm.compute(stk, ctx, opt, txn, doc).await?;
|
||||
stm.compute(stk, ctx, opt, doc).await?;
|
||||
// Ok all good
|
||||
Ok(Value::None)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ pub use user::DefineUserStatement;
|
|||
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::Options;
|
||||
use crate::dbs::Transaction;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
|
@ -66,22 +65,21 @@ impl DefineStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Self::Namespace(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Database(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Function(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Param(ref v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Table(ref v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Event(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Field(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Index(ref v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Self::Analyzer(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::User(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Model(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Access(ref v) => v.compute(ctx, opt, txn, doc).await,
|
||||
Self::Namespace(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Database(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Function(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Param(ref v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Table(ref v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Event(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Field(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Index(ref v) => v.compute(stk, ctx, opt, doc).await,
|
||||
Self::Analyzer(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::User(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Model(ref v) => v.compute(ctx, opt, doc).await,
|
||||
Self::Access(ref v) => v.compute(ctx, opt, doc).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -52,15 +52,14 @@ impl DefineModelStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Model, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if model already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -26,9 +26,8 @@ impl DefineNamespaceStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
|
@ -36,7 +35,7 @@ impl DefineNamespaceStatement {
|
|||
// Process the statement
|
||||
let key = crate::key::root::ns::new(&self.name);
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if namespace already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -32,13 +32,12 @@ impl DefineParamStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Parameter, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if param already exists
|
||||
|
@ -55,7 +54,7 @@ impl DefineParamStatement {
|
|||
key,
|
||||
DefineParamStatement {
|
||||
// Compute the param
|
||||
value: self.value.compute(stk, ctx, opt, txn, doc).await?,
|
||||
value: self.value.compute(stk, ctx, opt, doc).await?,
|
||||
// Don't persist the "IF NOT EXISTS" clause to schema
|
||||
if_not_exists: false,
|
||||
..self.clone()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Force, Options, Transaction};
|
||||
use crate::dbs::{Force, Options};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -46,13 +46,12 @@ impl DefineTableStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
opt.is_allowed(Action::Edit, ResourceKind::Table, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if table already exists
|
||||
|
@ -133,7 +132,7 @@ impl DefineTableStatement {
|
|||
what: Values(vec![Value::Table(v.clone())]),
|
||||
..UpdateStatement::default()
|
||||
};
|
||||
stm.compute(stk, ctx, opt, txn, doc).await?;
|
||||
stm.compute(stk, ctx, opt, doc).await?;
|
||||
}
|
||||
} else if dt.changefeed.is_some() {
|
||||
run.record_table_change(opt.ns(), opt.db(), self.name.0.as_str(), &dt);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::{Action, ResourceKind};
|
||||
|
@ -80,9 +80,8 @@ impl DefineUserStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
|
@ -91,7 +90,7 @@ impl DefineUserStatement {
|
|||
match self.base {
|
||||
Base::Root => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if user already exists
|
||||
|
@ -116,7 +115,7 @@ impl DefineUserStatement {
|
|||
}
|
||||
Base::Ns => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if user already exists
|
||||
|
@ -143,7 +142,7 @@ impl DefineUserStatement {
|
|||
}
|
||||
Base::Db => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Clear the cache
|
||||
run.clear_cache();
|
||||
// Check if user already exists
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Iterator, Options, Statement, Transaction};
|
||||
use crate::dbs::{Iterator, Options, Statement};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{Cond, Output, Timeout, Value, Values};
|
||||
|
@ -34,7 +34,6 @@ impl DeleteStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Valid options?
|
||||
|
@ -47,8 +46,8 @@ impl DeleteStatement {
|
|||
let opt = &opt.new_with_futures(false).with_projections(false);
|
||||
// Loop over the delete targets
|
||||
for w in self.what.0.iter() {
|
||||
let v = w.compute(stk, ctx, opt, txn, doc).await?;
|
||||
i.prepare(stk, ctx, opt, txn, &stm, v).await.map_err(|e| match e {
|
||||
let v = w.compute(stk, ctx, opt, doc).await?;
|
||||
i.prepare(stk, ctx, opt, &stm, v).await.map_err(|e| match e {
|
||||
Error::InvalidStatementTarget {
|
||||
value: v,
|
||||
} => Error::DeleteStatement {
|
||||
|
@ -58,7 +57,7 @@ impl DeleteStatement {
|
|||
})?;
|
||||
}
|
||||
// Output the results
|
||||
match i.output(stk, ctx, opt, txn, &stm).await? {
|
||||
match i.output(stk, ctx, opt, &stm).await? {
|
||||
// This is a single record result
|
||||
Value::Array(mut a) if self.only => match a.len() {
|
||||
// There was exactly one result
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{block::Entry, Block, Param, Value};
|
||||
|
@ -32,11 +32,10 @@ impl ForeachStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check the loop data
|
||||
match &self.range.compute(stk, ctx, opt, txn, doc).await? {
|
||||
match &self.range.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Array(arr) => {
|
||||
// Loop over the values
|
||||
'foreach: for v in arr.iter() {
|
||||
|
@ -44,55 +43,38 @@ impl ForeachStatement {
|
|||
let mut ctx = Context::new(ctx);
|
||||
// Set the current parameter
|
||||
let key = self.param.0.to_raw();
|
||||
let val = stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await?;
|
||||
let val = stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await?;
|
||||
ctx.add_value(key, val);
|
||||
// Loop over the code block statements
|
||||
for v in self.block.iter() {
|
||||
// Compute each block entry
|
||||
let res = match v {
|
||||
Entry::Set(v) => {
|
||||
let val =
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await?;
|
||||
let val = stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await?;
|
||||
ctx.add_value(v.name.to_owned(), val);
|
||||
Ok(Value::None)
|
||||
}
|
||||
Entry::Value(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Break(v) => v.compute(&ctx, opt, txn, doc).await,
|
||||
Entry::Continue(v) => v.compute(&ctx, opt, txn, doc).await,
|
||||
Entry::Value(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Break(v) => v.compute(&ctx, opt, doc).await,
|
||||
Entry::Continue(v) => v.compute(&ctx, opt, doc).await,
|
||||
Entry::Foreach(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await
|
||||
}
|
||||
Entry::Ifelse(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Select(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Create(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Update(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Delete(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Relate(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Insert(v) => {
|
||||
stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await
|
||||
}
|
||||
Entry::Define(v) => v.compute(stk, &ctx, opt, txn, doc).await,
|
||||
Entry::Rebuild(v) => v.compute(stk, &ctx, opt, txn, doc).await,
|
||||
Entry::Remove(v) => v.compute(&ctx, opt, txn, doc).await,
|
||||
Entry::Ifelse(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Select(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Create(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Update(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Delete(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Relate(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Insert(v) => stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await,
|
||||
Entry::Define(v) => v.compute(stk, &ctx, opt, doc).await,
|
||||
Entry::Rebuild(v) => v.compute(stk, &ctx, opt, doc).await,
|
||||
Entry::Remove(v) => v.compute(&ctx, opt, doc).await,
|
||||
Entry::Output(v) => {
|
||||
return stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await;
|
||||
return stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await;
|
||||
}
|
||||
Entry::Throw(v) => {
|
||||
return stk.run(|stk| v.compute(stk, &ctx, opt, txn, doc)).await;
|
||||
return stk.run(|stk| v.compute(stk, &ctx, opt, doc)).await;
|
||||
}
|
||||
};
|
||||
// Catch any special errors
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::fmt::{fmt_separated_by, is_pretty, pretty_indent, Fmt, Pretty};
|
||||
|
@ -43,17 +43,16 @@ impl IfelseStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
for (ref cond, ref then) in &self.exprs {
|
||||
let v = cond.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let v = cond.compute(stk, ctx, opt, doc).await?;
|
||||
if v.is_truthy() {
|
||||
return then.compute(stk, ctx, opt, txn, doc).await;
|
||||
return then.compute(stk, ctx, opt, doc).await;
|
||||
}
|
||||
}
|
||||
match self.close {
|
||||
Some(ref v) => v.compute(stk, ctx, opt, txn, doc).await,
|
||||
Some(ref v) => v.compute(stk, ctx, opt, doc).await,
|
||||
None => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::iam::Action;
|
||||
|
@ -66,9 +66,8 @@ impl InfoStatement {
|
|||
/// Process this type returning a computed simple Value
|
||||
pub(crate) async fn compute(
|
||||
&self,
|
||||
_ctx: &Context<'_>,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Allowed to run?
|
||||
|
@ -77,7 +76,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Root)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the namespaces
|
||||
|
@ -99,7 +98,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Ns)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the databases
|
||||
|
@ -127,7 +126,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the users
|
||||
|
@ -179,7 +178,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the events
|
||||
|
@ -221,7 +220,7 @@ impl InfoStatement {
|
|||
opt.is_allowed(Action::View, ResourceKind::Actor, &base)?;
|
||||
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Process the user
|
||||
let res = match base {
|
||||
Base::Root => run.get_root_user(user).await?,
|
||||
|
@ -236,7 +235,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Root)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the namespaces
|
||||
|
@ -250,7 +249,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Ns)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the databases
|
||||
|
@ -269,7 +268,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the users
|
||||
|
@ -316,7 +315,7 @@ impl InfoStatement {
|
|||
// Allowed to run?
|
||||
opt.is_allowed(Action::View, ResourceKind::Any, &Base::Db)?;
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Create the result set
|
||||
let mut res = Object::default();
|
||||
// Process the events
|
||||
|
@ -353,7 +352,7 @@ impl InfoStatement {
|
|||
opt.is_allowed(Action::View, ResourceKind::Actor, &base)?;
|
||||
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Process the user
|
||||
let res = match base {
|
||||
Base::Root => run.get_root_user(user).await?,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Iterable, Iterator, Options, Statement, Transaction};
|
||||
use crate::dbs::{Iterable, Iterator, Options, Statement};
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::sql::{Data, Output, Timeout, Value};
|
||||
|
@ -34,7 +34,6 @@ impl InsertStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Valid options?
|
||||
|
@ -44,7 +43,7 @@ impl InsertStatement {
|
|||
// Ensure futures are stored
|
||||
let opt = &opt.new_with_futures(false).with_projections(false);
|
||||
// Parse the expression
|
||||
match self.into.compute(stk, ctx, opt, txn, doc).await? {
|
||||
match self.into.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Table(into) => match &self.data {
|
||||
// Check if this is a traditional statement
|
||||
Data::ValuesExpression(v) => {
|
||||
|
@ -53,8 +52,8 @@ impl InsertStatement {
|
|||
let mut o = Value::base();
|
||||
// Set each field from the expression
|
||||
for (k, v) in v.iter() {
|
||||
let v = v.compute(stk, ctx, opt, txn, None).await?;
|
||||
o.set(stk, ctx, opt, txn, k, v).await?;
|
||||
let v = v.compute(stk, ctx, opt, None).await?;
|
||||
o.set(stk, ctx, opt, k, v).await?;
|
||||
}
|
||||
// Specify the new table record id
|
||||
let id = o.rid().generate(&into, true)?;
|
||||
|
@ -64,7 +63,7 @@ impl InsertStatement {
|
|||
}
|
||||
// Check if this is a modern statement
|
||||
Data::SingleExpression(v) => {
|
||||
let v = v.compute(stk, ctx, opt, txn, doc).await?;
|
||||
let v = v.compute(stk, ctx, opt, doc).await?;
|
||||
match v {
|
||||
Value::Array(v) => {
|
||||
for v in v {
|
||||
|
@ -98,7 +97,7 @@ impl InsertStatement {
|
|||
// Assign the statement
|
||||
let stm = Statement::from(self);
|
||||
// Output the results
|
||||
i.output(stk, ctx, opt, txn, &stm).await
|
||||
i.output(stk, ctx, opt, &stm).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use revision::revisioned;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::Error;
|
||||
use crate::fflags::FFLAGS;
|
||||
|
@ -31,7 +31,6 @@ impl KillStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
_doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Is realtime enabled?
|
||||
|
@ -41,7 +40,7 @@ impl KillStatement {
|
|||
// Resolve live query id
|
||||
let live_query_id = match &self.id {
|
||||
Value::Uuid(id) => *id,
|
||||
Value::Param(param) => match param.compute(stk, ctx, opt, txn, None).await? {
|
||||
Value::Param(param) => match param.compute(stk, ctx, opt, None).await? {
|
||||
Value::Uuid(id) => id,
|
||||
Value::Strand(id) => match uuid::Uuid::try_parse(&id) {
|
||||
Ok(id) => Uuid(id),
|
||||
|
@ -75,7 +74,7 @@ impl KillStatement {
|
|||
}
|
||||
};
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
if FFLAGS.change_feed_live_queries.enabled() {
|
||||
run.pre_commit_register_async_event(TrackedResult::KillQuery(KillEntry {
|
||||
live_id: live_query_id,
|
||||
|
@ -155,10 +154,11 @@ mod test {
|
|||
let ds = Datastore::new("memory").await.unwrap();
|
||||
let tx =
|
||||
ds.transaction(TransactionType::Write, LockType::Optimistic).await.unwrap().enclose();
|
||||
let ctx = ctx.set_transaction(tx.clone());
|
||||
|
||||
let mut stack = reblessive::tree::TreeStack::new();
|
||||
|
||||
stack.enter(|stk| res.compute(stk, &ctx, &opt, &tx, None)).finish().await.unwrap();
|
||||
stack.enter(|stk| res.compute(stk, &ctx, &opt, None)).finish().await.unwrap();
|
||||
|
||||
let mut tx = tx.lock().await;
|
||||
tx.commit().await.unwrap();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::ctx::Context;
|
||||
use crate::dbs::{Options, Transaction};
|
||||
use crate::dbs::Options;
|
||||
use crate::doc::CursorDoc;
|
||||
use crate::err::{Error, LiveQueryCause};
|
||||
use crate::fflags::FFLAGS;
|
||||
|
@ -82,7 +82,6 @@ impl LiveStatement {
|
|||
stk: &mut Stk,
|
||||
ctx: &Context<'_>,
|
||||
opt: &Options,
|
||||
txn: &Transaction,
|
||||
doc: Option<&CursorDoc<'_>>,
|
||||
) -> Result<Value, Error> {
|
||||
// Is realtime enabled?
|
||||
|
@ -106,8 +105,8 @@ impl LiveStatement {
|
|||
let id = stm.id.0;
|
||||
match FFLAGS.change_feed_live_queries.enabled() {
|
||||
true => {
|
||||
let mut run = txn.lock().await;
|
||||
match stm.what.compute(stk, ctx, opt, txn, doc).await? {
|
||||
let mut run = ctx.tx_lock().await;
|
||||
match stm.what.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Table(tb) => {
|
||||
// We modify the table as it can be a $PARAM and the compute evaluates that
|
||||
let mut stm = stm;
|
||||
|
@ -134,9 +133,9 @@ impl LiveStatement {
|
|||
}
|
||||
false => {
|
||||
// Claim transaction
|
||||
let mut run = txn.lock().await;
|
||||
let mut run = ctx.tx_lock().await;
|
||||
// Process the live query table
|
||||
match stm.what.compute(stk, ctx, opt, txn, doc).await? {
|
||||
match stm.what.compute(stk, ctx, opt, doc).await? {
|
||||
Value::Table(tb) => {
|
||||
// Store the current Node ID
|
||||
stm.node = nid.into();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue