Resolve panics when a NS or a DB are not configured ()

Co-authored-by: Emmanuel Keller <emmanuel.keller@surrealdb.com>
This commit is contained in:
Gerard Guillemas Martos 2024-06-11 11:34:21 +02:00 committed by GitHub
parent a11f1bc82f
commit d9ae887d50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
54 changed files with 442 additions and 326 deletions

View file

@ -339,13 +339,13 @@ impl Options {
}
/// Get currently selected NS
pub fn ns(&self) -> &str {
self.ns.as_ref().map(AsRef::as_ref).unwrap()
pub fn ns(&self) -> Result<&str, Error> {
self.ns.as_ref().map(AsRef::as_ref).ok_or(Error::NsEmpty)
}
/// Get currently selected DB
pub fn db(&self) -> &str {
self.db.as_ref().map(AsRef::as_ref).unwrap()
pub fn db(&self) -> Result<&str, Error> {
self.db.as_ref().map(AsRef::as_ref).ok_or(Error::DbEmpty)
}
/// Check whether this request supports realtime queries
@ -379,14 +379,8 @@ impl Options {
// Validate the target resource and base
let res = match base {
Base::Root => res.on_root(),
Base::Ns => {
self.valid_for_ns()?;
res.on_ns(self.ns())
}
Base::Db => {
self.valid_for_db()?;
res.on_db(self.ns(), self.db())
}
Base::Ns => res.on_ns(self.ns()?),
Base::Db => res.on_db(self.ns()?, self.db()?),
// TODO(gguillemas): This variant is kept in 2.0.0 for backward compatibility. Drop in 3.0.0.
Base::Sc(_) => {
// We should not get here, the scope base is only used in parsing for backward compatibility.
@ -406,15 +400,15 @@ impl Options {
///
/// TODO: This method is called a lot during data operations, so we decided to bypass the system's authorization mechanism.
/// This is a temporary solution, until we optimize the new authorization system.
pub fn check_perms(&self, action: Action) -> bool {
pub fn check_perms(&self, action: Action) -> Result<bool, Error> {
// If permissions are disabled, don't check permissions
if !self.perms {
return false;
return Ok(false);
}
// If auth is disabled and actor is anonymous, don't check permissions
if !self.auth_enabled && self.auth.is_anon() {
return false;
return Ok(false);
}
// Is the actor allowed to view?
@ -424,10 +418,10 @@ impl Options {
let can_edit = [Role::Editor, Role::Owner].iter().any(|r| self.auth.has_role(r));
// Is the target database in the actor's level?
let db_in_actor_level = self.auth.is_root()
|| self.auth.is_ns() && self.auth.level().ns().unwrap() == self.ns()
|| self.auth.is_ns() && self.auth.level().ns().unwrap() == self.ns()?
|| self.auth.is_db()
&& self.auth.level().ns().unwrap() == self.ns()
&& self.auth.level().db().unwrap() == self.db();
&& self.auth.level().ns().unwrap() == self.ns()?
&& self.auth.level().db().unwrap() == self.db()?;
// Is the actor allowed to do the action on the selected database?
let is_allowed = match action {
@ -442,7 +436,7 @@ impl Options {
};
// Check permissions if the author is not already allowed to do the action
!is_allowed
Ok(!is_allowed)
}
}

View file

@ -187,9 +187,9 @@ impl<'a> Processor<'a> {
v: Thing,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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 key = thing::new(opt.ns()?, opt.db()?, &v.tb, &v.id);
let val = ctx.tx_lock().await.get(key).await?;
// Parse the data from the store
let val = Operable::Value(match val {
@ -216,7 +216,7 @@ impl<'a> Processor<'a> {
v: Thing,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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),
@ -238,9 +238,9 @@ impl<'a> Processor<'a> {
o: Value,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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 key = thing::new(opt.ns()?, opt.db()?, &v.tb, &v.id);
let val = ctx.tx_lock().await.get(key).await?;
// Parse the data from the store
let x = match val {
@ -273,9 +273,9 @@ impl<'a> Processor<'a> {
o: Option<Value>,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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 key = thing::new(opt.ns()?, opt.db()?, &v.tb, &v.id);
let val = ctx.tx_lock().await.get(key).await?;
// Parse the data from the store
let x = match val {
@ -304,10 +304,10 @@ impl<'a> Processor<'a> {
v: &Table,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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);
let beg = thing::prefix(opt.ns()?, opt.db()?, v);
let end = thing::suffix(opt.ns()?, opt.db()?, v);
// Loop until no more keys
let mut next_page = Some(ScanPage::from(beg..end));
while let Some(page) = next_page {
@ -358,23 +358,23 @@ impl<'a> Processor<'a> {
v: Range,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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),
Bound::Included(id) => thing::new(opt.ns(), opt.db(), &v.tb, id).encode().unwrap(),
Bound::Unbounded => thing::prefix(opt.ns()?, opt.db()?, &v.tb),
Bound::Included(id) => thing::new(opt.ns()?, opt.db()?, &v.tb, id).encode().unwrap(),
Bound::Excluded(id) => {
let mut key = thing::new(opt.ns(), opt.db(), &v.tb, id).encode().unwrap();
let mut key = thing::new(opt.ns()?, opt.db()?, &v.tb, id).encode().unwrap();
key.push(0x00);
key
}
};
// Prepare the range end key
let end = match &v.end {
Bound::Unbounded => thing::suffix(opt.ns(), opt.db(), &v.tb),
Bound::Excluded(id) => thing::new(opt.ns(), opt.db(), &v.tb, id).encode().unwrap(),
Bound::Unbounded => thing::suffix(opt.ns()?, opt.db()?, &v.tb),
Bound::Excluded(id) => thing::new(opt.ns()?, opt.db()?, &v.tb, id).encode().unwrap(),
Bound::Included(id) => {
let mut key = thing::new(opt.ns(), opt.db(), &v.tb, id).encode().unwrap();
let mut key = thing::new(opt.ns()?, opt.db()?, &v.tb, id).encode().unwrap();
key.push(0x00);
key
}
@ -429,8 +429,8 @@ impl<'a> Processor<'a> {
e: Edges,
) -> Result<(), Error> {
// Pull out options
let ns = opt.ns();
let db = opt.db();
let ns = opt.ns()?;
let db = opt.db()?;
let tb = &e.from.tb;
let id = &e.from.id;
// Fetch start and end key pairs
@ -522,7 +522,7 @@ impl<'a> Processor<'a> {
// Parse the data from the store
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 key = thing::new(opt.ns()?, opt.db()?, gra.ft, &gra.fk);
let val = ctx.tx_lock().await.get(key).await?;
let rid = Thing::from((gra.ft, gra.fk));
// Parse the data from the store
@ -555,7 +555,7 @@ impl<'a> Processor<'a> {
irf: IteratorRef,
) -> Result<(), Error> {
// Check that the table exists
ctx.tx_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
@ -623,7 +623,7 @@ impl Iterable {
thg: &Thing,
) -> Result<Value, Error> {
// Fetch the data from the store
let key = thing::new(opt.ns(), opt.db(), &thg.tb, &thg.id);
let key = thing::new(opt.ns()?, opt.db()?, &thg.tb, &thg.id);
// Fetch and parse the data from the store
let val = tx.get(key).await?.map(Value::from).unwrap_or(Value::None);
// Return the result

View file

@ -17,7 +17,7 @@ impl<'a> Document<'a> {
// Check if this record exists
if self.id.is_some() {
// Should we run permissions checks?
if opt.check_perms(stm.into()) {
if opt.check_perms(stm.into())? {
// Get the table
let tb = self.tb(ctx, opt).await?;
// Get the permission clause

View file

@ -20,7 +20,7 @@ impl<'a> Document<'a> {
// Claim transaction
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?;
let db = run.add_and_cache_db(opt.ns()?, opt.db()?, opt.strict).await?;
// Check if changefeeds are enabled
if let Some(cf) = db.as_ref().changefeed.as_ref().or(tb.as_ref().changefeed.as_ref()) {
// Get the arguments
@ -28,8 +28,8 @@ impl<'a> Document<'a> {
let id = self.id.as_ref().unwrap();
// Create the changefeed entry
run.record_change(
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
tb,
id,
self.initial.doc.clone(),

View file

@ -50,7 +50,7 @@ impl<'a> Document<'a> {
// we load the new record, and reprocess
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 key = crate::key::thing::new(opt.ns()?, opt.db()?, &v.tb, &v.id);
let val = ctx.tx_lock().await.get(key).await?;
// Parse the data from the store
let val = match val {

View file

@ -152,7 +152,7 @@ impl<'a> Document<'a> {
// Get the record id
let rid = self.id.as_ref().unwrap();
// Get the table definition
let tb = run.get_and_cache_tb(opt.ns(), opt.db(), &rid.tb).await;
let tb = run.get_and_cache_tb(opt.ns()?, opt.db()?, &rid.tb).await;
// Return the table or attempt to define it
match tb {
// The table doesn't exist
@ -162,9 +162,9 @@ impl<'a> Document<'a> {
// Allowed to run?
opt.is_allowed(Action::Edit, ResourceKind::Table, &Base::Db)?;
// We can create the table automatically
run.add_and_cache_ns(opt.ns(), opt.strict).await?;
run.add_and_cache_db(opt.ns(), opt.db(), opt.strict).await?;
run.add_and_cache_tb(opt.ns(), opt.db(), &rid.tb, opt.strict).await
run.add_and_cache_ns(opt.ns()?, opt.strict).await?;
run.add_and_cache_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.add_and_cache_tb(opt.ns()?, opt.db()?, &rid.tb, opt.strict).await
}
// There was an error
Err(err) => Err(err),
@ -181,7 +181,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the table definitions
ctx.tx_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(
@ -192,7 +192,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the event definitions
ctx.tx_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(
@ -203,7 +203,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the field definitions
ctx.tx_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(
@ -214,7 +214,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the index definitions
ctx.tx_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(
@ -225,6 +225,6 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the table definition
ctx.tx_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
}
}

View file

@ -30,16 +30,16 @@ impl<'a> Document<'a> {
// Get temporary edge references
let (ref o, ref i) = (Dir::Out, Dir::In);
// Store the left pointer edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &l.tb, &l.id, o, rid);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &l.tb, &l.id, o, rid);
run.set(key, vec![]).await?;
// Store the left inner edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &rid.tb, &rid.id, i, l);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id, i, l);
run.set(key, vec![]).await?;
// Store the right inner edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &rid.tb, &rid.id, o, r);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id, o, r);
run.set(key, vec![]).await?;
// Store the right pointer edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &r.tb, &r.id, i, rid);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &r.tb, &r.id, i, rid);
run.set(key, vec![]).await?;
// Store the edges on the record
self.current.doc.to_mut().put(&*EDGE, Value::Bool(true));

View file

@ -127,7 +127,7 @@ impl<'a> Document<'a> {
}
}
// Check for a PERMISSIONS clause
if opt.check_perms(Action::Edit) {
if opt.check_perms(Action::Edit)? {
// Get the permission clause
let perms = if self.is_new() {
&fd.permissions.create

View file

@ -257,26 +257,26 @@ impl<'a> IndexOperation<'a> {
}
}
fn get_unique_index_key(&self, v: &'a Array) -> key::index::Index {
crate::key::index::Index::new(
self.opt.ns(),
self.opt.db(),
fn get_unique_index_key(&self, v: &'a Array) -> Result<key::index::Index, Error> {
Ok(crate::key::index::Index::new(
self.opt.ns()?,
self.opt.db()?,
&self.ix.what,
&self.ix.name,
v,
None,
)
))
}
fn get_non_unique_index_key(&self, v: &'a Array) -> key::index::Index {
crate::key::index::Index::new(
self.opt.ns(),
self.opt.db(),
fn get_non_unique_index_key(&self, v: &'a Array) -> Result<key::index::Index, Error> {
Ok(crate::key::index::Index::new(
self.opt.ns()?,
self.opt.db()?,
&self.ix.what,
&self.ix.name,
v,
Some(&self.rid.id),
)
))
}
async fn index_unique(&mut self, ctx: &Context<'_>) -> Result<(), Error> {
@ -285,7 +285,7 @@ impl<'a> IndexOperation<'a> {
if let Some(o) = self.o.take() {
let i = Indexable::new(o, self.ix);
for o in i {
let key = self.get_unique_index_key(&o);
let key = self.get_unique_index_key(&o)?;
match run.delc(key, Some(self.rid)).await {
Err(Error::TxConditionNotMet) => Ok(()),
Err(e) => Err(e),
@ -298,9 +298,9 @@ impl<'a> IndexOperation<'a> {
let i = Indexable::new(n, self.ix);
for n in i {
if !n.is_all_none_or_null() {
let key = self.get_unique_index_key(&n);
let key = self.get_unique_index_key(&n)?;
if run.putc(key, self.rid, None).await.is_err() {
let key = self.get_unique_index_key(&n);
let key = self.get_unique_index_key(&n)?;
let val = run.get(key).await?.unwrap();
let rid: Thing = val.into();
return self.err_index_exists(rid, n);
@ -317,7 +317,7 @@ impl<'a> IndexOperation<'a> {
if let Some(o) = self.o.take() {
let i = Indexable::new(o, self.ix);
for o in i {
let key = self.get_non_unique_index_key(&o);
let key = self.get_non_unique_index_key(&o)?;
match run.delc(key, Some(self.rid)).await {
Err(Error::TxConditionNotMet) => Ok(()),
Err(e) => Err(e),
@ -329,9 +329,9 @@ impl<'a> IndexOperation<'a> {
if let Some(n) = self.n.take() {
let i = Indexable::new(n, self.ix);
for n in i {
let key = self.get_non_unique_index_key(&n);
let key = self.get_non_unique_index_key(&n)?;
if run.putc(key, self.rid, None).await.is_err() {
let key = self.get_non_unique_index_key(&n);
let key = self.get_non_unique_index_key(&n)?;
let val = run.get(key).await?.unwrap();
let rid: Thing = val.into();
return self.err_index_exists(rid, n);
@ -358,7 +358,7 @@ impl<'a> IndexOperation<'a> {
ctx: &Context<'_>,
p: &SearchParams,
) -> Result<(), Error> {
let ikb = IndexKeyBase::new(self.opt, self.ix);
let ikb = IndexKeyBase::new(self.opt.ns()?, self.opt.db()?, self.ix)?;
let mut ft = FtIndex::new(ctx, self.opt, &p.az, ikb, p, TransactionType::Write).await?;
@ -377,7 +377,7 @@ impl<'a> IndexOperation<'a> {
p: &MTreeParams,
) -> Result<(), Error> {
let mut tx = ctx.tx_lock().await;
let ikb = IndexKeyBase::new(self.opt, self.ix);
let ikb = IndexKeyBase::new(self.opt.ns()?, self.opt.db()?, self.ix)?;
let mut mt =
MTreeIndex::new(ctx.get_index_stores(), &mut tx, ikb, p, TransactionType::Write)
.await?;
@ -393,7 +393,7 @@ impl<'a> IndexOperation<'a> {
}
async fn index_hnsw(&mut self, ctx: &Context<'_>, p: &HnswParams) -> Result<(), Error> {
let hnsw = ctx.get_index_stores().get_index_hnsw(self.opt, self.ix, p).await;
let hnsw = ctx.get_index_stores().get_index_hnsw(self.opt, self.ix, p).await?;
let mut hnsw = hnsw.write().await;
// Delete the old index data
if let Some(o) = self.o.take() {

View file

@ -79,7 +79,7 @@ impl<'a> Document<'a> {
doc: &CursorDoc<'_>,
) -> Result<(), Error> {
// Should we run permissions checks?
if opt.check_perms(stm.into()) {
if opt.check_perms(stm.into())? {
// Get the table
let tb = self.tb(ctx, opt).await?;
// Process the table permissions

View file

@ -76,7 +76,7 @@ impl<'a> Document<'a> {
// Check if this record exists
if self.id.is_some() {
// Should we run permissions checks?
if opt.check_perms(Action::View) {
if opt.check_perms(Action::View)? {
// Loop through all field statements
for fd in self.fd(ctx, opt).await?.iter() {
// Loop over each field in document

View file

@ -44,7 +44,7 @@ impl<'a> Document<'a> {
// we load the new record, and reprocess
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 key = crate::key::thing::new(opt.ns()?, opt.db()?, &v.tb, &v.id);
let val = ctx.tx_lock().await.get(key).await?;
// Parse the data from the store
let val = match val {

View file

@ -30,7 +30,7 @@ impl<'a> Document<'a> {
// Get the record id
if let Some(rid) = self.id {
// Purge the record data
let key = crate::key::thing::new(opt.ns(), opt.db(), &rid.tb, &rid.id);
let key = crate::key::thing::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id);
run.del(key).await?;
// Purge the record edges
match (
@ -42,16 +42,16 @@ impl<'a> Document<'a> {
// Get temporary edge references
let (ref o, ref i) = (Dir::Out, Dir::In);
// Purge the left pointer edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &l.tb, &l.id, o, rid);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &l.tb, &l.id, o, rid);
run.del(key).await?;
// Purge the left inner edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &rid.tb, &rid.id, i, l);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id, i, l);
run.del(key).await?;
// Purge the right inner edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &rid.tb, &rid.id, o, r);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id, o, r);
run.del(key).await?;
// Purge the right pointer edge
let key = crate::key::graph::new(opt.ns(), opt.db(), &r.tb, &r.id, i, rid);
let key = crate::key::graph::new(opt.ns()?, opt.db()?, &r.tb, &r.id, i, rid);
run.del(key).await?;
}
_ => {

View file

@ -25,7 +25,7 @@ impl<'a> Document<'a> {
// Get the record id
let rid = self.id.as_ref().unwrap();
// Store the record data
let key = crate::key::thing::new(opt.ns(), opt.db(), &rid.tb, &rid.id);
let key = crate::key::thing::new(opt.ns()?, opt.db()?, &rid.tb, &rid.id);
//
match stm {
// This is a CREATE statement so try to insert the key

View file

@ -14,7 +14,7 @@ pub async fn analyze(
) -> Result<Value, Error> {
if let (Some(opt), Value::Strand(az), Value::Strand(val)) = (opt, az, val) {
let az: Analyzer =
ctx.tx_lock().await.get_db_analyzer(opt.ns(), opt.db(), az.as_str()).await?.into();
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)

View file

@ -106,7 +106,7 @@ impl FtIndex {
tt: TransactionType,
) -> Result<Self, Error> {
let mut tx = ctx.tx_lock().await;
let az = tx.get_db_analyzer(opt.ns(), opt.db(), az).await?;
let az = tx.get_db_analyzer(opt.ns()?, opt.db()?, az).await?;
let res =
Self::with_analyzer(ctx.get_index_stores(), &mut tx, az, index_key_base, p, tt).await;
drop(tx);

View file

@ -3,7 +3,6 @@ pub(crate) mod ft;
pub mod planner;
pub mod trees;
use crate::dbs::Options;
use crate::err::Error;
use crate::idx::docids::DocId;
use crate::idx::ft::terms::TermId;
@ -42,15 +41,15 @@ struct Inner {
}
impl IndexKeyBase {
pub(crate) fn new(opt: &Options, ix: &DefineIndexStatement) -> Self {
Self {
pub(crate) fn new(ns: &str, db: &str, ix: &DefineIndexStatement) -> Result<Self, Error> {
Ok(Self {
inner: Arc::new(Inner {
ns: opt.ns().to_string(),
db: opt.db().to_string(),
ns: ns.to_string(),
db: db.to_string(),
tb: ix.what.to_string(),
ix: ix.name.to_string(),
}),
}
})
}
fn new_bc_key(&self, term_id: TermId) -> Key {

View file

@ -132,7 +132,7 @@ impl InnerQueryExecutor {
let ft_entry = match ft_map.entry(ix_ref) {
Entry::Occupied(e) => FtEntry::new(stk, ctx, opt, e.get(), io).await?,
Entry::Vacant(e) => {
let ikb = IndexKeyBase::new(opt, idx_def);
let ikb = IndexKeyBase::new(opt.ns()?, opt.db()?, idx_def)?;
let ft = FtIndex::new(
ctx,
opt,
@ -174,7 +174,7 @@ impl InnerQueryExecutor {
.await?
}
Entry::Vacant(e) => {
let ikb = IndexKeyBase::new(opt, idx_def);
let ikb = IndexKeyBase::new(opt.ns()?, opt.db()?, idx_def)?;
let mut tx = ctx.tx_lock().await;
let mt = MTreeIndex::new(
ctx.get_index_stores(),
@ -222,7 +222,7 @@ impl InnerQueryExecutor {
let hnsw = ctx
.get_index_stores()
.get_index_hnsw(opt, idx_def, p)
.await;
.await?;
let entry = HnswEntry::new(
stk,
ctx,
@ -346,7 +346,7 @@ impl QueryExecutor {
match it_entry {
IteratorEntry::Single(_, io) => self.new_single_iterator(opt, irf, io).await,
IteratorEntry::Range(_, ixr, from, to) => {
Ok(self.new_range_iterator(opt, *ixr, from, to))
Ok(self.new_range_iterator(opt, *ixr, from, to)?)
}
}
} else {
@ -386,19 +386,19 @@ impl QueryExecutor {
IndexOperator::Equality(value) | IndexOperator::Exactness(value) => {
Some(ThingIterator::IndexEqual(IndexEqualThingIterator::new(
irf,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
&ix.what,
&ix.name,
value,
)))
}
IndexOperator::Union(value) => Some(ThingIterator::IndexUnion(
IndexUnionThingIterator::new(irf, opt.ns(), opt.db(), &ix.what, &ix.name, value),
IndexUnionThingIterator::new(irf, opt.ns()?, opt.db()?, &ix.what, &ix.name, value),
)),
IndexOperator::Join(ios) => {
let iterators = self.build_iterators(opt, irf, ios).await?;
let index_join = Box::new(IndexJoinThingIterator::new(irf, opt, ix, iterators));
let index_join = Box::new(IndexJoinThingIterator::new(irf, opt, ix, iterators)?);
Some(ThingIterator::IndexJoin(index_join))
}
_ => None,
@ -411,35 +411,35 @@ impl QueryExecutor {
ir: IndexRef,
from: &RangeValue,
to: &RangeValue,
) -> Option<ThingIterator> {
) -> Result<Option<ThingIterator>, Error> {
if let Some(ix) = self.get_index_def(ir) {
match ix.index {
Index::Idx => {
return Some(ThingIterator::IndexRange(IndexRangeThingIterator::new(
return Ok(Some(ThingIterator::IndexRange(IndexRangeThingIterator::new(
ir,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
&ix.what,
&ix.name,
from,
to,
)))
))))
}
Index::Uniq => {
return Some(ThingIterator::UniqueRange(UniqueRangeThingIterator::new(
return Ok(Some(ThingIterator::UniqueRange(UniqueRangeThingIterator::new(
ir,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
&ix.what,
&ix.name,
from,
to,
)))
))))
}
_ => {}
}
}
None
Ok(None)
}
async fn new_unique_index_iterator(
@ -453,19 +453,19 @@ impl QueryExecutor {
IndexOperator::Equality(value) | IndexOperator::Exactness(value) => {
Some(ThingIterator::UniqueEqual(UniqueEqualThingIterator::new(
irf,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
&ix.what,
&ix.name,
value,
)))
}
IndexOperator::Union(value) => {
Some(ThingIterator::UniqueUnion(UniqueUnionThingIterator::new(irf, opt, ix, value)))
}
IndexOperator::Union(value) => Some(ThingIterator::UniqueUnion(
UniqueUnionThingIterator::new(irf, opt, ix, value)?,
)),
IndexOperator::Join(ios) => {
let iterators = self.build_iterators(opt, irf, ios).await?;
let unique_join = Box::new(UniqueJoinThingIterator::new(irf, opt, ix, iterators));
let unique_join = Box::new(UniqueJoinThingIterator::new(irf, opt, ix, iterators)?);
Some(ThingIterator::UniqueJoin(unique_join))
}
_ => None,

View file

@ -404,10 +404,10 @@ impl JoinThingIterator {
opt: &Options,
ix: &DefineIndexStatement,
remote_iterators: VecDeque<ThingIterator>,
) -> Self {
Self {
ns: opt.ns().to_string(),
db: opt.db().to_string(),
) -> Result<Self, Error> {
Ok(Self {
ns: opt.ns()?.to_string(),
db: opt.db()?.to_string(),
ix_what: ix.what.clone(),
ix_name: ix.name.clone(),
current_remote: None,
@ -415,7 +415,7 @@ impl JoinThingIterator {
remote_iterators,
current_local: None,
distinct: Default::default(),
}
})
}
}
@ -501,8 +501,8 @@ impl IndexJoinThingIterator {
opt: &Options,
ix: &DefineIndexStatement,
remote_iterators: VecDeque<ThingIterator>,
) -> Self {
Self(irf, JoinThingIterator::new(opt, ix, remote_iterators))
) -> Result<Self, Error> {
Ok(Self(irf, JoinThingIterator::new(opt, ix, remote_iterators)?))
}
async fn next_batch<B: IteratorBatch>(
@ -663,20 +663,20 @@ impl UniqueUnionThingIterator {
opt: &Options,
ix: &DefineIndexStatement,
a: &Array,
) -> Self {
) -> Result<Self, Error> {
// We create a VecDeque to hold the key for each value in the array.
let keys: VecDeque<Key> =
a.0.iter()
.map(|v| {
.map(|v| -> Result<Key, Error> {
let a = Array::from(v.clone());
let key = Index::new(opt.ns(), opt.db(), &ix.what, &ix.name, &a, None).into();
key
let key = Index::new(opt.ns()?, opt.db()?, &ix.what, &ix.name, &a, None).into();
Ok(key)
})
.collect();
Self {
.collect::<Result<VecDeque<Key>, Error>>()?;
Ok(Self {
irf,
keys,
}
})
}
async fn next_batch<B: IteratorBatch>(
@ -710,8 +710,8 @@ impl UniqueJoinThingIterator {
opt: &Options,
ix: &DefineIndexStatement,
remote_iterators: VecDeque<ThingIterator>,
) -> Self {
Self(irf, JoinThingIterator::new(opt, ix, remote_iterators))
) -> Result<Self, Error> {
Ok(Self(irf, JoinThingIterator::new(opt, ix, remote_iterators)?))
}
async fn next_batch<B: IteratorBatch>(

View file

@ -545,8 +545,8 @@ struct SchemaCache {
impl SchemaCache {
async fn new(opt: &Options, table: &Table, tx: &mut kvs::Transaction) -> Result<Self, Error> {
let indexes = tx.all_tb_indexes(opt.ns(), opt.db(), table).await?;
let fields = tx.all_tb_fields(opt.ns(), opt.db(), table).await?;
let indexes = tx.all_tb_indexes(opt.ns()?, opt.db()?, table).await?;
let fields = tx.all_tb_fields(opt.ns()?, opt.db()?, table).await?;
Ok(Self {
indexes,
fields,

View file

@ -283,50 +283,65 @@ impl IndexStores {
opt: &Options,
ix: &DefineIndexStatement,
p: &HnswParams,
) -> SharedHnswIndex {
let ikb = IndexKeyBase::new(opt, ix);
self.0.hnsw_indexes.get(&ikb, p).await
) -> Result<SharedHnswIndex, Error> {
let ikb = IndexKeyBase::new(opt.ns()?, opt.db()?, ix)?;
Ok(self.0.hnsw_indexes.get(&ikb, p).await)
}
pub(crate) async fn index_removed(
&self,
opt: &Options,
tx: &mut Transaction,
ns: &str,
db: &str,
tb: &str,
ix: &str,
) -> Result<(), Error> {
self.remove_index(
opt,
tx.get_and_cache_tb_index(opt.ns(), opt.db(), tb, ix).await?.as_ref(),
)
.await
self.remove_index(ns, db, tx.get_and_cache_tb_index(ns, db, tb, ix).await?.as_ref()).await
}
pub(crate) async fn namespace_removed(
&self,
opt: &Options,
tx: &mut Transaction,
ns: &str,
) -> Result<(), Error> {
for tb in tx.all_tb(opt.ns(), opt.db()).await?.iter() {
self.table_removed(opt, tx, &tb.name).await?;
for db in tx.all_db(ns).await?.iter() {
self.database_removed(tx, ns, &db.name).await?;
}
Ok(())
}
pub(crate) async fn database_removed(
&self,
tx: &mut Transaction,
ns: &str,
db: &str,
) -> Result<(), Error> {
for tb in tx.all_tb(ns, db).await?.iter() {
self.table_removed(tx, ns, db, &tb.name).await?;
}
Ok(())
}
pub(crate) async fn table_removed(
&self,
opt: &Options,
tx: &mut Transaction,
ns: &str,
db: &str,
tb: &str,
) -> Result<(), Error> {
for ix in tx.all_tb_indexes(opt.ns(), opt.db(), tb).await?.iter() {
self.remove_index(opt, ix).await?;
for ix in tx.all_tb_indexes(ns, db, tb).await?.iter() {
self.remove_index(ns, db, ix).await?;
}
Ok(())
}
async fn remove_index(&self, opt: &Options, ix: &DefineIndexStatement) -> Result<(), Error> {
let ikb = IndexKeyBase::new(opt, ix);
async fn remove_index(
&self,
ns: &str,
db: &str,
ix: &DefineIndexStatement,
) -> Result<(), Error> {
let ikb = IndexKeyBase::new(ns, db, ix)?;
match ix.index {
Index::Search(_) => {
self.remove_search_caches(ikb);

View file

@ -205,8 +205,6 @@ impl Function {
fnc::run(stk, ctx, opt, doc, s, a).await
}
Self::Custom(s, x) => {
// Check that a database is set to prevent a panic
opt.valid_for_db()?;
// Get the full name of this function
let name = format!("fn::{s}");
// Check this function is allowed
@ -216,12 +214,12 @@ impl Function {
// Claim transaction
let mut run = ctx.tx_lock().await;
// Get the function definition
let val = 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) {
if opt.check_perms(Action::View)? {
match &val.permissions {
Permission::Full => (),
Permission::None => {

View file

@ -71,21 +71,21 @@ impl Model {
let mut run = ctx.tx_lock().await;
// Get the function definition
let val =
run.get_and_cache_db_model(opt.ns(), opt.db(), &self.name, &self.version).await?;
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!(
"ml/{}/{}/{}-{}-{}.surml",
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
self.name,
self.version,
val.hash
);
// Check permissions
if opt.check_perms(Action::View) {
if opt.check_perms(Action::View)? {
match &val.permissions {
Permission::Full => (),
Permission::None => {

View file

@ -69,20 +69,18 @@ impl Param {
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 = ctx.tx_lock().await;
// Get the param definition
run.get_and_cache_db_param(opt.ns(), opt.db(), v).await
run.get_and_cache_db_param(opt.ns()?, opt.db()?, v).await
};
// Check if the param has been set globally
match val {
// The param has been set globally
Ok(val) => {
// Check permissions
if opt.check_perms(Action::View) {
if opt.check_perms(Action::View)? {
match &val.permissions {
Permission::Full => (),
Permission::None => {

View file

@ -41,9 +41,9 @@ impl AnalyzeStatement {
let ix = ctx
.tx_lock()
.await
.get_and_cache_tb_index(opt.ns(), opt.db(), tb.as_str(), idx.as_str())
.get_and_cache_tb_index(opt.ns()?, opt.db()?, tb, idx)
.await?;
let ikb = IndexKeyBase::new(opt, &ix);
let ikb = IndexKeyBase::new(opt.ns()?, opt.db()?, &ix)?;
// Index operation dispatching
let value: Value = match &ix.index {

View file

@ -66,7 +66,7 @@ impl DefineAccessStatement {
// Clear the cache
run.clear_cache();
// Check if access method already exists
if run.get_ns_access(opt.ns(), &self.name).await.is_ok() {
if run.get_ns_access(opt.ns()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -76,8 +76,8 @@ impl DefineAccessStatement {
}
}
// Process the statement
let key = crate::key::namespace::ac::new(opt.ns(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
let key = crate::key::namespace::ac::new(opt.ns()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.set(
key,
DefineAccessStatement {
@ -95,7 +95,7 @@ impl DefineAccessStatement {
// Clear the cache
run.clear_cache();
// Check if access method already exists
if run.get_db_access(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_db_access(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -105,9 +105,9 @@ impl DefineAccessStatement {
}
}
// Process the statement
let key = crate::key::database::ac::new(opt.ns(), opt.db(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::ac::new(opt.ns()?, opt.db()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.set(
key,
DefineAccessStatement {

View file

@ -39,7 +39,7 @@ impl DefineAnalyzerStatement {
// Clear the cache
run.clear_cache();
// Check if analyzer already exists
if run.get_db_analyzer(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_db_analyzer(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -49,9 +49,9 @@ impl DefineAnalyzerStatement {
}
}
// Process the statement
let key = crate::key::database::az::new(opt.ns(), opt.db(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::az::new(opt.ns()?, opt.db()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
// Persist the definition
run.set(
key,

View file

@ -38,7 +38,7 @@ impl DefineDatabaseStatement {
// Clear the cache
run.clear_cache();
// Check if database already exists
if run.get_db(opt.ns(), &self.name).await.is_ok() {
if run.get_db(opt.ns()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -48,8 +48,8 @@ impl DefineDatabaseStatement {
}
}
// Process the statement
let key = crate::key::namespace::db::new(opt.ns(), &self.name);
let ns = run.add_ns(opt.ns(), opt.strict).await?;
let key = crate::key::namespace::db::new(opt.ns()?, &self.name);
let ns = run.add_ns(opt.ns()?, opt.strict).await?;
// Set the id
if self.id.is_none() && ns.id.is_some() {
// Set the id

View file

@ -39,7 +39,7 @@ impl DefineEventStatement {
// Clear the cache
run.clear_cache();
// Check if event already exists
if run.get_tb_event(opt.ns(), opt.db(), &self.what, &self.name).await.is_ok() {
if run.get_tb_event(opt.ns()?, opt.db()?, &self.what, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -49,10 +49,10 @@ impl DefineEventStatement {
}
}
// Process the statement
let key = crate::key::table::ev::new(opt.ns(), opt.db(), &self.what, &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
run.add_tb(opt.ns(), opt.db(), &self.what, opt.strict).await?;
let key = crate::key::table::ev::new(opt.ns()?, opt.db()?, &self.what, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.add_tb(opt.ns()?, opt.db()?, &self.what, opt.strict).await?;
run.set(
key,
DefineEventStatement {
@ -62,7 +62,7 @@ impl DefineEventStatement {
)
.await?;
// Clear the cache
let key = crate::key::table::ev::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::ev::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -51,7 +51,7 @@ impl DefineFieldStatement {
run.clear_cache();
// Check if field already exists
let fd = self.name.to_string();
if run.get_tb_field(opt.ns(), opt.db(), &self.what, &fd).await.is_ok() {
if run.get_tb_field(opt.ns()?, opt.db()?, &self.what, &fd).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -61,11 +61,11 @@ impl DefineFieldStatement {
}
}
// Process the statement
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
let tb = run.add_tb(opt.ns(), opt.db(), &self.what, opt.strict).await?;
let key = crate::key::table::fd::new(opt.ns(), opt.db(), &self.what, &fd);
let tb = run.add_tb(opt.ns()?, opt.db()?, &self.what, opt.strict).await?;
let key = crate::key::table::fd::new(opt.ns()?, opt.db()?, &self.what, &fd);
run.set(
key,
DefineFieldStatement {
@ -76,7 +76,7 @@ impl DefineFieldStatement {
.await?;
// find existing field definitions.
let fields = run.all_tb_fields(opt.ns(), opt.db(), &self.what).await.ok();
let fields = run.all_tb_fields(opt.ns()?, opt.db()?, &self.what).await.ok();
// Process possible recursive_definitions.
if let Some(mut cur_kind) = self.kind.as_ref().and_then(|x| x.inner_kind()) {
@ -86,9 +86,9 @@ impl DefineFieldStatement {
name.0.push(Part::All);
let fd = name.to_string();
let key = crate::key::table::fd::new(opt.ns(), opt.db(), &self.what, &fd);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::table::fd::new(opt.ns()?, opt.db()?, &self.what, &fd);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
// merge the new definition with possible existing definitions.
let statement = if let Some(existing) =
@ -155,14 +155,14 @@ impl DefineFieldStatement {
_ => None,
};
if let Some(tb) = new_tb {
let key = crate::key::database::tb::new(opt.ns(), opt.db(), &self.what);
let key = crate::key::database::tb::new(opt.ns()?, opt.db()?, &self.what);
run.set(key, &tb).await?;
let key = crate::key::table::ft::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::ft::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
}
// Clear the cache
let key = crate::key::table::fd::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::fd::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -42,7 +42,7 @@ impl DefineFunctionStatement {
// Clear the cache
run.clear_cache();
// Check if function already exists
if run.get_db_function(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_db_function(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -52,9 +52,9 @@ impl DefineFunctionStatement {
}
}
// Process the statement
let key = crate::key::database::fc::new(opt.ns(), opt.db(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::fc::new(opt.ns()?, opt.db()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.set(
key,
DefineFunctionStatement {

View file

@ -44,7 +44,7 @@ impl DefineIndexStatement {
// Clear the cache
run.clear_cache();
// Check if index already exists
if run.get_tb_index(opt.ns(), opt.db(), &self.what, &self.name).await.is_ok() {
if run.get_tb_index(opt.ns()?, opt.db()?, &self.what, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -54,16 +54,16 @@ impl DefineIndexStatement {
}
}
// If we are strict, check that the table exists
run.check_ns_db_tb(opt.ns(), opt.db(), &self.what, opt.strict).await?;
run.check_ns_db_tb(opt.ns()?, opt.db()?, &self.what, opt.strict).await?;
// Does the table exists?
match run.get_and_cache_tb(opt.ns(), opt.db(), &self.what).await {
match run.get_and_cache_tb(opt.ns()?, opt.db()?, &self.what).await {
Ok(db) => {
// Are we SchemaFull?
if db.full {
// Check that the fields exists
for idiom in self.cols.iter() {
if let Some(Part::Field(id)) = idiom.first() {
run.get_tb_field(opt.ns(), opt.db(), &self.what, id).await?;
run.get_tb_field(opt.ns()?, opt.db()?, &self.what, id).await?;
}
}
}
@ -77,10 +77,10 @@ impl DefineIndexStatement {
}
// Process the statement
let key = crate::key::table::ix::new(opt.ns(), opt.db(), &self.what, &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
run.add_tb(opt.ns(), opt.db(), &self.what, opt.strict).await?;
let key = crate::key::table::ix::new(opt.ns()?, opt.db()?, &self.what, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.add_tb(opt.ns()?, opt.db()?, &self.what, opt.strict).await?;
run.set(
key,
DefineIndexStatement {
@ -91,10 +91,10 @@ impl DefineIndexStatement {
)
.await?;
// Remove the index data
let key = crate::key::index::all::new(opt.ns(), opt.db(), &self.what, &self.name);
let key = crate::key::index::all::new(opt.ns()?, opt.db()?, &self.what, &self.name);
run.delp(key, u32::MAX).await?;
// Clear the cache
let key = crate::key::table::ix::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::ix::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
// Release the transaction
drop(run);

View file

@ -63,7 +63,7 @@ impl DefineModelStatement {
// Clear the cache
run.clear_cache();
// Check if model already exists
if run.get_db_model(opt.ns(), opt.db(), &self.name, &self.version).await.is_ok() {
if run.get_db_model(opt.ns()?, opt.db()?, &self.name, &self.version).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -73,9 +73,9 @@ impl DefineModelStatement {
}
}
// Process the statement
let key = crate::key::database::ml::new(opt.ns(), opt.db(), &self.name, &self.version);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::ml::new(opt.ns()?, opt.db()?, &self.name, &self.version);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.set(
key,
DefineModelStatement {

View file

@ -41,7 +41,7 @@ impl DefineParamStatement {
// Clear the cache
run.clear_cache();
// Check if param already exists
if run.get_db_param(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_db_param(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -51,9 +51,9 @@ impl DefineParamStatement {
}
}
// Process the statement
let key = crate::key::database::pa::new(opt.ns(), opt.db(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::pa::new(opt.ns()?, opt.db()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.set(
key,
DefineParamStatement {

View file

@ -55,7 +55,7 @@ impl DefineTableStatement {
// Clear the cache
run.clear_cache();
// Check if table already exists
if run.get_tb(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_tb(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
@ -65,9 +65,9 @@ impl DefineTableStatement {
}
}
// Process the statement
let key = crate::key::database::tb::new(opt.ns(), opt.db(), &self.name);
let ns = run.add_ns(opt.ns(), opt.strict).await?;
let db = run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::tb::new(opt.ns()?, opt.db()?, &self.name);
let ns = run.add_ns(opt.ns()?, opt.strict).await?;
let db = run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
let dt = if self.id.is_none() && ns.id.is_some() && db.id.is_some() {
DefineTableStatement {
id: Some(run.get_next_tb_id(ns.id.unwrap(), db.id.unwrap()).await?),
@ -84,8 +84,8 @@ impl DefineTableStatement {
let tb: &str = &self.name;
let in_kind = rel.from.clone().unwrap_or(Kind::Record(vec![]));
let out_kind = rel.to.clone().unwrap_or(Kind::Record(vec![]));
let in_key = crate::key::table::fd::new(opt.ns(), opt.db(), tb, "in");
let out_key = crate::key::table::fd::new(opt.ns(), opt.db(), tb, "out");
let in_key = crate::key::table::fd::new(opt.ns()?, opt.db()?, tb, "in");
let out_key = crate::key::table::fd::new(opt.ns()?, opt.db()?, tb, "out");
run.set(
in_key,
DefineFieldStatement {
@ -108,21 +108,21 @@ impl DefineTableStatement {
.await?;
}
let tb_key = crate::key::table::fd::prefix(opt.ns(), opt.db(), &self.name);
let tb_key = crate::key::table::fd::prefix(opt.ns()?, opt.db()?, &self.name);
run.clr(tb_key).await?;
run.set(key, &dt).await?;
// Check if table is a view
if let Some(view) = &self.view {
// Remove the table data
let key = crate::key::table::all::new(opt.ns(), opt.db(), &self.name);
let key = crate::key::table::all::new(opt.ns()?, opt.db()?, &self.name);
run.delp(key, u32::MAX).await?;
// Process each foreign table
for v in view.what.0.iter() {
// Save the view config
let key = crate::key::table::ft::new(opt.ns(), opt.db(), v, &self.name);
let key = crate::key::table::ft::new(opt.ns()?, opt.db()?, v, &self.name);
run.set(key, self).await?;
// Clear the cache
let key = crate::key::table::ft::prefix(opt.ns(), opt.db(), v);
let key = crate::key::table::ft::prefix(opt.ns()?, opt.db()?, v);
run.clr(key).await?;
}
// Release the transaction
@ -139,7 +139,7 @@ impl DefineTableStatement {
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);
run.record_table_change(opt.ns()?, opt.db()?, self.name.0.as_str(), &dt);
}
// Ok all good

View file

@ -142,19 +142,19 @@ impl DefineUserStatement {
// Clear the cache
run.clear_cache();
// Check if user already exists
if run.get_ns_user(opt.ns(), &self.name).await.is_ok() {
if run.get_ns_user(opt.ns()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
return Err(Error::UserNsAlreadyExists {
value: self.name.to_string(),
ns: opt.ns().into(),
ns: opt.ns()?.into(),
});
}
}
// Process the statement
let key = crate::key::namespace::us::new(opt.ns(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
let key = crate::key::namespace::us::new(opt.ns()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.set(
key,
DefineUserStatement {
@ -173,21 +173,21 @@ impl DefineUserStatement {
// Clear the cache
run.clear_cache();
// Check if user already exists
if run.get_db_user(opt.ns(), opt.db(), &self.name).await.is_ok() {
if run.get_db_user(opt.ns()?, opt.db()?, &self.name).await.is_ok() {
if self.if_not_exists {
return Ok(Value::None);
} else {
return Err(Error::UserDbAlreadyExists {
value: self.name.to_string(),
ns: opt.ns().into(),
db: opt.db().into(),
ns: opt.ns()?.into(),
db: opt.db()?.into(),
});
}
}
// Process the statement
let key = crate::key::database::us::new(opt.ns(), opt.db(), &self.name);
run.add_ns(opt.ns(), opt.strict).await?;
run.add_db(opt.ns(), opt.db(), opt.strict).await?;
let key = crate::key::database::us::new(opt.ns()?, opt.db()?, &self.name);
run.add_ns(opt.ns()?, opt.strict).await?;
run.add_db(opt.ns()?, opt.db()?, opt.strict).await?;
run.set(
key,
DefineUserStatement {

View file

@ -103,19 +103,19 @@ impl InfoStatement {
let mut res = Object::default();
// Process the databases
let mut tmp = Object::default();
for v in run.all_db(opt.ns()).await?.iter() {
for v in run.all_db(opt.ns()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("databases".to_owned(), tmp.into());
// Process the users
let mut tmp = Object::default();
for v in run.all_ns_users(opt.ns()).await?.iter() {
for v in run.all_ns_users(opt.ns()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("users".to_owned(), tmp.into());
// Process the accesses
let mut tmp = Object::default();
for v in run.all_ns_accesses_redacted(opt.ns()).await?.iter() {
for v in run.all_ns_accesses_redacted(opt.ns()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("accesses".to_owned(), tmp.into());
@ -131,43 +131,43 @@ impl InfoStatement {
let mut res = Object::default();
// Process the users
let mut tmp = Object::default();
for v in run.all_db_users(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_users(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("users".to_owned(), tmp.into());
// Process the functions
let mut tmp = Object::default();
for v in run.all_db_functions(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_functions(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("functions".to_owned(), tmp.into());
// Process the models
let mut tmp = Object::default();
for v in run.all_db_models(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_models(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(format!("{}<{}>", v.name, v.version), v.to_string().into());
}
res.insert("models".to_owned(), tmp.into());
// Process the params
let mut tmp = Object::default();
for v in run.all_db_params(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_params(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("params".to_owned(), tmp.into());
// Process the accesses
let mut tmp = Object::default();
for v in run.all_db_accesses_redacted(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_accesses_redacted(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("accesses".to_owned(), tmp.into());
// Process the tables
let mut tmp = Object::default();
for v in run.all_tb(opt.ns(), opt.db()).await?.iter() {
for v in run.all_tb(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("tables".to_owned(), tmp.into());
// Process the analyzers
let mut tmp = Object::default();
for v in run.all_db_analyzers(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_analyzers(opt.ns()?, opt.db()?).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("analyzers".to_owned(), tmp.into());
@ -183,31 +183,31 @@ impl InfoStatement {
let mut res = Object::default();
// Process the events
let mut tmp = Object::default();
for v in run.all_tb_events(opt.ns(), opt.db(), tb).await?.iter() {
for v in run.all_tb_events(opt.ns()?, opt.db()?, tb).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("events".to_owned(), tmp.into());
// Process the fields
let mut tmp = Object::default();
for v in run.all_tb_fields(opt.ns(), opt.db(), tb).await?.iter() {
for v in run.all_tb_fields(opt.ns()?, opt.db()?, tb).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("fields".to_owned(), tmp.into());
// Process the tables
let mut tmp = Object::default();
for v in run.all_tb_views(opt.ns(), opt.db(), tb).await?.iter() {
for v in run.all_tb_views(opt.ns()?, opt.db()?, tb).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("tables".to_owned(), tmp.into());
// Process the indexes
let mut tmp = Object::default();
for v in run.all_tb_indexes(opt.ns(), opt.db(), tb).await?.iter() {
for v in run.all_tb_indexes(opt.ns()?, opt.db()?, tb).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("indexes".to_owned(), tmp.into());
// Process the live queries
let mut tmp = Object::default();
for v in run.all_tb_lives(opt.ns(), opt.db(), tb).await?.iter() {
for v in run.all_tb_lives(opt.ns()?, opt.db()?, tb).await?.iter() {
tmp.insert(v.id.to_raw(), v.to_string().into());
}
res.insert("lives".to_owned(), tmp.into());
@ -224,8 +224,8 @@ impl InfoStatement {
// Process the user
let res = match base {
Base::Root => run.get_root_user(user).await?,
Base::Ns => run.get_ns_user(opt.ns(), user).await?,
Base::Db => run.get_db_user(opt.ns(), opt.db(), user).await?,
Base::Ns => run.get_ns_user(opt.ns()?, user).await?,
Base::Db => run.get_db_user(opt.ns()?, opt.db()?, user).await?,
_ => return Err(Error::InvalidLevel(base.to_string())),
};
// Ok all good
@ -253,13 +253,13 @@ impl InfoStatement {
// Create the result set
let mut res = Object::default();
// Process the databases
res.insert("databases".to_owned(), process_arr(run.all_db(opt.ns()).await?));
res.insert("databases".to_owned(), process_arr(run.all_db(opt.ns()?).await?));
// Process the users
res.insert("users".to_owned(), process_arr(run.all_ns_users(opt.ns()).await?));
res.insert("users".to_owned(), process_arr(run.all_ns_users(opt.ns()?).await?));
// Process the accesses
res.insert(
"accesses".to_owned(),
process_arr(run.all_ns_accesses_redacted(opt.ns()).await?),
process_arr(run.all_ns_accesses_redacted(opt.ns()?).await?),
);
// Ok all good
Value::from(res).ok()
@ -274,39 +274,42 @@ impl InfoStatement {
// Process the users
res.insert(
"users".to_owned(),
process_arr(run.all_db_users(opt.ns(), opt.db()).await?),
process_arr(run.all_db_users(opt.ns()?, opt.db()?).await?),
);
// Process the accesses
res.insert(
"accesses".to_owned(),
process_arr(run.all_db_accesses(opt.ns(), opt.db()).await?),
process_arr(run.all_db_accesses(opt.ns()?, opt.db()?).await?),
);
// Process the functions
res.insert(
"functions".to_owned(),
process_arr(run.all_db_functions(opt.ns(), opt.db()).await?),
process_arr(run.all_db_functions(opt.ns()?, opt.db()?).await?),
);
// Process the models
res.insert(
"models".to_owned(),
process_arr(run.all_db_models(opt.ns(), opt.db()).await?),
process_arr(run.all_db_models(opt.ns()?, opt.db()?).await?),
);
// Process the params
res.insert(
"params".to_owned(),
process_arr(run.all_db_params(opt.ns(), opt.db()).await?),
process_arr(run.all_db_params(opt.ns()?, opt.db()?).await?),
);
// Process the accesses
res.insert(
"accesses".to_owned(),
process_arr(run.all_db_accesses_redacted(opt.ns(), opt.db()).await?),
process_arr(run.all_db_accesses_redacted(opt.ns()?, opt.db()?).await?),
);
// Process the tables
res.insert("tables".to_owned(), process_arr(run.all_tb(opt.ns(), opt.db()).await?));
res.insert(
"tables".to_owned(),
process_arr(run.all_tb(opt.ns()?, opt.db()?).await?),
);
// Process the analyzers
res.insert(
"analyzers".to_owned(),
process_arr(run.all_db_analyzers(opt.ns(), opt.db()).await?),
process_arr(run.all_db_analyzers(opt.ns()?, opt.db()?).await?),
);
// Ok all good
Value::from(res).ok()
@ -321,27 +324,27 @@ impl InfoStatement {
// Process the events
res.insert(
"events".to_owned(),
process_arr(run.all_tb_events(opt.ns(), opt.db(), tb).await?),
process_arr(run.all_tb_events(opt.ns()?, opt.db()?, tb).await?),
);
// Process the fields
res.insert(
"fields".to_owned(),
process_arr(run.all_tb_fields(opt.ns(), opt.db(), tb).await?),
process_arr(run.all_tb_fields(opt.ns()?, opt.db()?, tb).await?),
);
// Process the tables
res.insert(
"tables".to_owned(),
process_arr(run.all_tb_views(opt.ns(), opt.db(), tb).await?),
process_arr(run.all_tb_views(opt.ns()?, opt.db()?, tb).await?),
);
// Process the indexes
res.insert(
"indexes".to_owned(),
process_arr(run.all_tb_indexes(opt.ns(), opt.db(), tb).await?),
process_arr(run.all_tb_indexes(opt.ns()?, opt.db()?, tb).await?),
);
// Process the live queries
res.insert(
"lives".to_owned(),
process_arr(run.all_tb_lives(opt.ns(), opt.db(), tb).await?),
process_arr(run.all_tb_lives(opt.ns()?, opt.db()?, tb).await?),
);
// Ok all good
Value::from(res).ok()
@ -356,8 +359,8 @@ impl InfoStatement {
// Process the user
let res = match base {
Base::Root => run.get_root_user(user).await?,
Base::Ns => run.get_ns_user(opt.ns(), user).await?,
Base::Db => run.get_db_user(opt.ns(), opt.db(), user).await?,
Base::Ns => run.get_ns_user(opt.ns()?, user).await?,
Base::Db => run.get_db_user(opt.ns()?, opt.db()?, user).await?,
_ => return Err(Error::InvalidLevel(base.to_string())),
};
// Ok all good

View file

@ -78,12 +78,12 @@ impl KillStatement {
if FFLAGS.change_feed_live_queries.enabled() {
run.pre_commit_register_async_event(TrackedResult::KillQuery(KillEntry {
live_id: live_query_id,
ns: opt.ns().to_string(),
db: opt.db().to_string(),
ns: opt.ns()?.to_string(),
db: opt.db()?.to_string(),
}))?;
} else {
// Fetch the live query key
let key = crate::key::node::lq::new(opt.id()?, live_query_id.0, opt.ns(), opt.db());
let key = crate::key::node::lq::new(opt.id()?, live_query_id.0, opt.ns()?, opt.db()?);
// Fetch the live query key if it exists
match run.get(key).await? {
Some(val) => match std::str::from_utf8(&val) {
@ -92,13 +92,13 @@ impl KillStatement {
let key = crate::key::node::lq::new(
opt.id()?,
live_query_id.0,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
);
run.del(key).await?;
// Delete the table live query
let key =
crate::key::table::lq::new(opt.ns(), opt.db(), tb, live_query_id.0);
crate::key::table::lq::new(opt.ns()?, opt.db()?, tb, live_query_id.0);
run.del(key).await?;
}
_ => {

View file

@ -112,8 +112,8 @@ impl LiveStatement {
let mut stm = stm;
stm.what = Value::Table(tb.clone());
let ns = opt.ns().to_string();
let db = opt.db().to_string();
let ns = opt.ns()?.to_string();
let db = opt.db()?.to_string();
self.validate_change_feed_valid(&mut run, &ns, &db, &tb).await?;
// Send the live query registration hook to the transaction pre-commit channel
run.pre_commit_register_async_event(TrackedResult::LiveQuery(LqEntry {
@ -140,9 +140,9 @@ impl LiveStatement {
// Store the current Node ID
stm.node = nid.into();
// Insert the node live query
run.putc_ndlq(nid, id, opt.ns(), opt.db(), tb.as_str(), None).await?;
run.putc_ndlq(nid, id, opt.ns()?, opt.db()?, tb.as_str(), None).await?;
// Insert the table live query
run.putc_tblq(opt.ns(), opt.db(), &tb, stm, None).await?;
run.putc_tblq(opt.ns()?, opt.db()?, &tb, stm, None).await?;
}
v => {
return Err(Error::LiveStatement {

View file

@ -76,7 +76,12 @@ impl RebuildIndexStatement {
let ix = ctx
.tx_lock()
.await
.get_and_cache_tb_index(opt.ns(), opt.db(), self.what.as_str(), self.name.as_str())
.get_and_cache_tb_index(
opt.ns()?,
opt.db()?,
self.what.as_str(),
self.name.as_str(),
)
.await?;
// Remove the index

View file

@ -33,9 +33,9 @@ impl RemoveAccessStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let ac = run.get_ns_access(opt.ns(), &self.name).await?;
let ac = run.get_ns_access(opt.ns()?, &self.name).await?;
// Delete the definition
let key = crate::key::namespace::ac::new(opt.ns(), &ac.name);
let key = crate::key::namespace::ac::new(opt.ns()?, &ac.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)
@ -46,9 +46,9 @@ impl RemoveAccessStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let ac = run.get_db_access(opt.ns(), opt.db(), &self.name).await?;
let ac = run.get_db_access(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::ac::new(opt.ns(), opt.db(), &ac.name);
let key = crate::key::database::ac::new(opt.ns()?, opt.db()?, &ac.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -28,9 +28,9 @@ impl RemoveAnalyzerStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let az = run.get_db_analyzer(opt.ns(), opt.db(), &self.name).await?;
let az = run.get_db_analyzer(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::az::new(opt.ns(), opt.db(), &az.name);
let key = crate::key::database::az::new(opt.ns()?, opt.db()?, &az.name);
run.del(key).await?;
// TODO Check that the analyzer is not used in any schema
// Ok all good

View file

@ -26,15 +26,17 @@ impl RemoveDatabaseStatement {
opt.is_allowed(Action::Edit, ResourceKind::Database, &Base::Ns)?;
// Claim transaction
let mut run = ctx.tx_lock().await;
// Remove index store
ctx.get_index_stores().database_removed(&mut run, opt.ns()?, &self.name).await?;
// Clear the cache
run.clear_cache();
// Get the definition
let db = run.get_db(opt.ns(), &self.name).await?;
let db = run.get_db(opt.ns()?, &self.name).await?;
// Delete the definition
let key = crate::key::namespace::db::new(opt.ns(), &db.name);
let key = crate::key::namespace::db::new(opt.ns()?, &db.name);
run.del(key).await?;
// Delete the resource data
let key = crate::key::database::all::new(opt.ns(), &db.name);
let key = crate::key::database::all::new(opt.ns()?, &db.name);
run.delp(key, u32::MAX).await?;
// Ok all good
Ok(Value::None)

View file

@ -30,12 +30,12 @@ impl RemoveEventStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let ev = run.get_tb_event(opt.ns(), opt.db(), &self.what, &self.name).await?;
let ev = run.get_tb_event(opt.ns()?, opt.db()?, &self.what, &self.name).await?;
// Delete the definition
let key = crate::key::table::ev::new(opt.ns(), opt.db(), &ev.what, &ev.name);
let key = crate::key::table::ev::new(opt.ns()?, opt.db()?, &ev.what, &ev.name);
run.del(key).await?;
// Clear the cache
let key = crate::key::table::ev::prefix(opt.ns(), opt.db(), &ev.what);
let key = crate::key::table::ev::prefix(opt.ns()?, opt.db()?, &ev.what);
run.clr(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -31,13 +31,13 @@ impl RemoveFieldStatement {
run.clear_cache();
// Get the definition
let fd_name = self.name.to_string();
let fd = run.get_tb_field(opt.ns(), opt.db(), &self.what, &fd_name).await?;
let fd = run.get_tb_field(opt.ns()?, opt.db()?, &self.what, &fd_name).await?;
// Delete the definition
let fd_name = fd.name.to_string();
let key = crate::key::table::fd::new(opt.ns(), opt.db(), &self.what, &fd_name);
let key = crate::key::table::fd::new(opt.ns()?, opt.db()?, &self.what, &fd_name);
run.del(key).await?;
// Clear the cache
let key = crate::key::table::fd::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::fd::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -29,9 +29,9 @@ impl RemoveFunctionStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let fc = run.get_db_function(opt.ns(), opt.db(), &self.name).await?;
let fc = run.get_db_function(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::fc::new(opt.ns(), opt.db(), &fc.name);
let key = crate::key::database::fc::new(opt.ns()?, opt.db()?, &fc.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -28,17 +28,19 @@ impl RemoveIndexStatement {
// Claim transaction
let mut run = ctx.tx_lock().await;
// Clear the index store cache
ctx.get_index_stores().index_removed(opt, &mut run, &self.what, &self.name).await?;
ctx.get_index_stores()
.index_removed(&mut run, opt.ns()?, opt.db()?, &self.what, &self.name)
.await?;
// Clear the cache
run.clear_cache();
// Delete the definition
let key = crate::key::table::ix::new(opt.ns(), opt.db(), &self.what, &self.name);
let key = crate::key::table::ix::new(opt.ns()?, opt.db()?, &self.what, &self.name);
run.del(key).await?;
// Remove the index data
let key = crate::key::index::all::new(opt.ns(), opt.db(), &self.what, &self.name);
let key = crate::key::index::all::new(opt.ns()?, opt.db()?, &self.what, &self.name);
run.delp(key, u32::MAX).await?;
// Clear the cache
let key = crate::key::table::ix::prefix(opt.ns(), opt.db(), &self.what);
let key = crate::key::table::ix::prefix(opt.ns()?, opt.db()?, &self.what);
run.clr(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -30,7 +30,8 @@ impl RemoveModelStatement {
// Clear the cache
run.clear_cache();
// Delete the definition
let key = crate::key::database::ml::new(opt.ns(), opt.db(), &self.name, &self.version);
let key =
crate::key::database::ml::new(opt.ns()?, opt.db()?, &self.name, &self.version);
run.del(key).await?;
// Remove the model file
// TODO

View file

@ -26,7 +26,8 @@ impl RemoveNamespaceStatement {
opt.is_allowed(Action::Edit, ResourceKind::Namespace, &Base::Root)?;
// Claim transaction
let mut run = ctx.tx_lock().await;
ctx.get_index_stores().namespace_removed(opt, &mut run).await?;
// Delete index stores instance
ctx.get_index_stores().namespace_removed(&mut run, &self.name).await?;
// Clear the cache
run.clear_cache();
// Get the definition

View file

@ -29,9 +29,9 @@ impl RemoveParamStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let pa = run.get_db_param(opt.ns(), opt.db(), &self.name).await?;
let pa = run.get_db_param(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::pa::new(opt.ns(), opt.db(), &pa.name);
let key = crate::key::database::pa::new(opt.ns()?, opt.db()?, &pa.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -27,23 +27,25 @@ impl RemoveTableStatement {
// Claim transaction
let mut run = ctx.tx_lock().await;
// Remove the index stores
ctx.get_index_stores().table_removed(opt, &mut run, &self.name).await?;
ctx.get_index_stores()
.table_removed(&mut run, opt.ns()?, opt.db()?, &self.name)
.await?;
// Clear the cache
run.clear_cache();
// Get the defined table
let tb = run.get_tb(opt.ns(), opt.db(), &self.name).await?;
let tb = run.get_tb(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::tb::new(opt.ns(), opt.db(), &self.name);
let key = crate::key::database::tb::new(opt.ns()?, opt.db()?, &self.name);
run.del(key).await?;
// Remove the resource data
let key = crate::key::table::all::new(opt.ns(), opt.db(), &self.name);
let key = crate::key::table::all::new(opt.ns()?, opt.db()?, &self.name);
run.delp(key, u32::MAX).await?;
// Check if this is a foreign table
if let Some(view) = &tb.view {
// Process each foreign table
for v in view.what.0.iter() {
// Save the view config
let key = crate::key::table::ft::new(opt.ns(), opt.db(), v, &self.name);
let key = crate::key::table::ft::new(opt.ns()?, opt.db()?, v, &self.name);
run.del(key).await?;
}
}

View file

@ -46,9 +46,9 @@ impl RemoveUserStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let us = run.get_ns_user(opt.ns(), &self.name).await?;
let us = run.get_ns_user(opt.ns()?, &self.name).await?;
// Delete the definition
let key = crate::key::namespace::us::new(opt.ns(), &us.name);
let key = crate::key::namespace::us::new(opt.ns()?, &us.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)
@ -59,9 +59,9 @@ impl RemoveUserStatement {
// Clear the cache
run.clear_cache();
// Get the definition
let us = run.get_db_user(opt.ns(), opt.db(), &self.name).await?;
let us = run.get_db_user(opt.ns()?, opt.db()?, &self.name).await?;
// Delete the definition
let key = crate::key::database::us::new(opt.ns(), opt.db(), &us.name);
let key = crate::key::database::us::new(opt.ns()?, opt.db()?, &us.name);
run.del(key).await?;
// Ok all good
Ok(Value::None)

View file

@ -60,8 +60,8 @@ impl ShowStatement {
let tb = self.table.as_deref();
let r = crate::cf::read(
&mut run,
opt.ns(),
opt.db(),
opt.ns()?,
opt.db()?,
tb.map(|x| x.as_str()),
self.since.clone(),
self.limit,

View file

@ -49,6 +49,102 @@ async fn remove_statement_table() -> Result<(), Error> {
Ok(())
}
#[tokio::test]
async fn remove_statement_namespace() -> Result<(), Error> {
// Namespace not selected
{
let sql = "
REMOVE NAMESPACE test;
DEFINE NAMESPACE test;
REMOVE NAMESPACE test;
";
let dbs = new_ds().await?;
let ses = Session::owner();
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 3);
//
let tmp = res.remove(0).result;
assert!(tmp.is_err());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
}
// Namespace selected
{
let sql = "
REMOVE NAMESPACE test;
DEFINE NAMESPACE test;
REMOVE NAMESPACE test;
";
let dbs = new_ds().await?;
// No namespace is selected
let ses = Session::owner().with_ns("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 3);
//
let tmp = res.remove(0).result;
assert!(tmp.is_err());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
}
Ok(())
}
#[tokio::test]
async fn remove_statement_database() -> Result<(), Error> {
// Database not selected
{
let sql = "
REMOVE DATABASE test;
DEFINE DATABASE test;
REMOVE DATABASE test;
";
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 3);
//
let tmp = res.remove(0).result;
assert!(tmp.is_err());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
}
// Database selected
{
let sql = "
REMOVE DATABASE test;
DEFINE DATABASE test;
REMOVE DATABASE test;
";
let dbs = new_ds().await?;
// No database is selected
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 3);
//
let tmp = res.remove(0).result;
assert!(tmp.is_err());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
//
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
}
Ok(())
}
#[tokio::test]
async fn remove_statement_analyzer() -> Result<(), Error> {
let sql = "