Ensure table is added if it does not exist

If the user is is creating a record in a table / collection that does not exist, and the user is authenticated with KV, NS, or DB level permissions, then we need to add the table with the default definition parameters.
This commit is contained in:
Tobie Morgan Hitchcock 2022-07-04 13:58:59 +01:00
parent 8ca211f96d
commit 8ebcff6d18
2 changed files with 34 additions and 32 deletions

View file

@ -1,3 +1,4 @@
use crate::dbs::Level;
use crate::dbs::Options;
use crate::dbs::Transaction;
use crate::dbs::Workable;
@ -52,7 +53,15 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the table definition
txn.clone().lock().await.get_tb(opt.ns(), opt.db(), &id.tb).await
let tb = txn.clone().lock().await.get_tb(opt.ns(), opt.db(), &id.tb).await;
// Return the table or attempt to define it
match tb {
Ok(tb) => Ok(tb),
Err(e) => match opt.auth.check(Level::Db) {
true => txn.clone().lock().await.add_tb(opt.ns(), opt.db(), &id.tb).await,
false => Err(e),
},
}
}
// Get the events for this document
pub async fn ev(

View file

@ -714,44 +714,37 @@ impl Transaction {
Ok(val.into())
}
/// Add a namespace with a default configuration.
pub async fn add_ns(&mut self, ns: &str) -> Result<(), Error> {
pub async fn add_ns(&mut self, ns: &str) -> Result<DefineNamespaceStatement, Error> {
let key = crate::key::ns::new(ns);
let _ = self
.put(
key,
DefineNamespaceStatement {
name: ns.to_owned().into(),
},
)
.await;
Ok(())
let val = DefineNamespaceStatement {
name: ns.to_owned().into(),
};
let _ = self.put(key, &val).await?;
Ok(val)
}
/// Add a database with a default configuration.
pub async fn add_db(&mut self, ns: &str, db: &str) -> Result<(), Error> {
pub async fn add_db(&mut self, ns: &str, db: &str) -> Result<DefineDatabaseStatement, Error> {
let key = crate::key::db::new(ns, db);
let _ = self
.put(
key,
DefineDatabaseStatement {
name: db.to_owned().into(),
},
)
.await;
Ok(())
let val = DefineDatabaseStatement {
name: db.to_owned().into(),
};
let _ = self.put(key, &val).await?;
Ok(val)
}
/// Add a table with a default configuration.
pub async fn add_tb(&mut self, ns: &str, db: &str, tb: &str) -> Result<(), Error> {
pub async fn add_tb(
&mut self,
ns: &str,
db: &str,
tb: &str,
) -> Result<DefineTableStatement, Error> {
let key = crate::key::tb::new(ns, db, tb);
let _ = self
.put(
key,
DefineTableStatement {
name: tb.to_owned().into(),
..DefineTableStatement::default()
},
)
.await;
Ok(())
let val = DefineTableStatement {
name: tb.to_owned().into(),
..DefineTableStatement::default()
};
let _ = self.put(key, &val).await?;
Ok(val)
}
/// Writes the full database contents as binary SQL.
pub async fn export(&mut self, ns: &str, db: &str, chn: Sender<Vec<u8>>) -> Result<(), Error> {