Optimisation - only loop over document fields when processing PERMISSIONS clauses (#1890)

This commit is contained in:
Tobie Morgan Hitchcock 2023-04-30 00:23:19 +01:00 committed by GitHub
parent 1e8903b699
commit c7e3b927ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 44 deletions

View file

@ -13,31 +13,31 @@ use std::sync::Arc;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Options {
// Currently selected NS
/// Currently selected NS
pub ns: Option<Arc<str>>,
// Currently selected DB
/// Currently selected DB
pub db: Option<Arc<str>>,
// Connection authentication data
/// Connection authentication data
pub auth: Arc<Auth>,
// Approximately how large is the current call stack?
/// Approximately how large is the current call stack?
dive: u8,
// Whether live queries are allowed?
/// Whether live queries are allowed?
pub live: bool,
// Should we force tables/events to re-run?
/// Should we force tables/events to re-run?
pub force: bool,
// Should we run permissions checks?
/// Should we run permissions checks?
pub perms: bool,
// Should we error if tables don't exist?
/// Should we error if tables don't exist?
pub strict: bool,
// Should we process field queries?
/// Should we process field queries?
pub fields: bool,
// Should we process event queries?
/// Should we process event queries?
pub events: bool,
// Should we process table queries?
/// Should we process table queries?
pub tables: bool,
// Should we process index queries?
/// Should we process index queries?
pub indexes: bool,
// Should we process function futures?
/// Should we process function futures?
pub futures: bool,
}

View file

@ -14,30 +14,33 @@ impl<'a> Document<'a> {
txn: &Transaction,
stm: &Statement<'_>,
) -> Result<(), Error> {
// Check permission clause
if opt.perms && opt.auth.perms() && self.id.is_some() {
// Get the table
let tb = self.tb(opt, txn).await?;
// Get the permission clause
let perms = if stm.is_delete() {
&tb.permissions.delete
} else if stm.is_select() {
&tb.permissions.select
} else if self.is_new() {
&tb.permissions.create
} else {
&tb.permissions.update
};
// Match the permission clause
match perms {
Permission::None => return Err(Error::Ignore),
Permission::Full => return Ok(()),
Permission::Specific(e) => {
// Disable permissions
let opt = &opt.perms(false);
// Process the PERMISSION clause
if !e.compute(ctx, opt, txn, Some(&self.current)).await?.is_truthy() {
return Err(Error::Ignore);
// Check if this record exists
if self.id.is_some() {
// Should we run permissions checks?
if opt.perms && opt.auth.perms() {
// Get the table
let tb = self.tb(opt, txn).await?;
// Get the permission clause
let perms = if stm.is_delete() {
&tb.permissions.delete
} else if stm.is_select() {
&tb.permissions.select
} else if self.is_new() {
&tb.permissions.create
} else {
&tb.permissions.update
};
// Process the table permissions
match perms {
Permission::None => return Err(Error::Ignore),
Permission::Full => return Ok(()),
Permission::Specific(e) => {
// Disable permissions
let opt = &opt.perms(false);
// Process the PERMISSION clause
if !e.compute(ctx, opt, txn, Some(&self.current)).await?.is_truthy() {
return Err(Error::Ignore);
}
}
}
}

View file

@ -55,13 +55,13 @@ impl<'a> Document<'a> {
}?;
// Check if this record exists
if self.id.is_some() {
// Loop through all field statements
for fd in self.fd(opt, txn).await?.iter() {
// Loop over each field in document
for k in out.each(&fd.name).iter() {
// Check for a PERMISSIONS clause
if opt.perms && opt.auth.perms() {
// Process field permissions
// Should we run permissions checks?
if opt.perms && opt.auth.perms() {
// Loop through all field statements
for fd in self.fd(opt, txn).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(ctx, opt, txn, k).await?,