From c7e3b927ac452667847b56a67a7a9d3b1d0bd2f5 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Sun, 30 Apr 2023 00:23:19 +0100 Subject: [PATCH] Optimisation - only loop over document fields when processing PERMISSIONS clauses (#1890) --- lib/src/dbs/options.rs | 26 ++++++++++----------- lib/src/doc/allow.rs | 51 ++++++++++++++++++++++-------------------- lib/src/doc/pluck.rs | 14 ++++++------ 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/lib/src/dbs/options.rs b/lib/src/dbs/options.rs index af4781fb..8f8c7438 100644 --- a/lib/src/dbs/options.rs +++ b/lib/src/dbs/options.rs @@ -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>, - // Currently selected DB + /// Currently selected DB pub db: Option>, - // Connection authentication data + /// Connection authentication data pub auth: Arc, - // 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, } diff --git a/lib/src/doc/allow.rs b/lib/src/doc/allow.rs index 9ae93346..996bbfb5 100644 --- a/lib/src/doc/allow.rs +++ b/lib/src/doc/allow.rs @@ -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); + } } } } diff --git a/lib/src/doc/pluck.rs b/lib/src/doc/pluck.rs index 360ccbe8..0316665b 100644 --- a/lib/src/doc/pluck.rs +++ b/lib/src/doc/pluck.rs @@ -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?,