Code cleanup (#2569)

This commit is contained in:
Tobie Morgan Hitchcock 2023-09-01 12:52:02 +01:00
parent ed48fddd2a
commit e9ee5245c2
29 changed files with 385 additions and 376 deletions

View file

@ -1,4 +1,4 @@
<h1><img height="25" src="./img/contributing.svg">&nbsp;&nbsp;Contributing</h1>
# Contributing
We would &nbsp;<img width="15" src="./img/love.svg">&nbsp; for you to contribute to SurrealDB and help make it better! We want contributing to SurrealDB to be fun, enjoyable, and educational for anyone and everyone. All contributions are welcome, including features, bugfixes, and documentation changes, as well as updates and tweaks, blog posts, workshops, and everything else.
@ -169,7 +169,7 @@ Pull requests are great, but there are many other areas where you can help.
### Blogging and speaking
Blogging, speaking about, or creating tutorials about one of SurrealDB's many features. Mention [@surrealdb](https://twitter.com/surrealdb) on Twitter, and email team@surrealdb.com so we can give pointers and tips and help you spread the word by promoting your content on the different SurrealDB communication channels. Please add your blog posts and videos of talks to our [showcase](https://github.com/surrealdb/showcase) repo on GitHub.
Blogging, speaking about, or creating tutorials about one of SurrealDB's many features. Mention [@surrealdb](https://twitter.com/surrealdb) on Twitter, and email community@surrealdb.com so we can give pointers and tips and help you spread the word by promoting your content on the different SurrealDB communication channels. Please add your blog posts and videos of talks to our [showcase](https://github.com/surrealdb/showcase) repo on GitHub.
### Presenting at meetups
@ -187,9 +187,11 @@ Submitting documentation updates, enhancements, designs, or bug fixes, and fixin
Join our growing community around the world, for help, ideas, and discussions regarding SurrealDB.
- View our official [Blog](https://medium.com/surrealdb)
- View our official [Blog](https://surrealdb.com/blog)
- Follow us on [Twitter](https://twitter.com/surrealdb)
- Connect with us on [LinkedIn](https://www.linkedin.com/company/surrealdb/)
- Join our [Dev community](https://dev.to/surrealdb)
- Chat live with us on [Discord](https://discord.gg/surrealdb)
- Get involved on [Reddit](http://reddit.com/r/surrealdb/)
- Read our blog posts on [Medium](https://medium.com/surrealdb)
- Questions tagged #surrealdb on [StackOverflow](https://stackoverflow.com/questions/tagged/surrealdb)

View file

@ -28,7 +28,7 @@ We absolutely agree! We intend to have a uniform, long-term approach with regard
### We need ORM support
We absolutely agree! We dont currently have ORM support in the drivers themselves, and arent likely to implemented this, as there are many ORM libraries and integrations with which to integrate. We are, however, very excited to discover what the community creates. We encourage both newcomers and existing members to explore various projects that address their needs - these can be found in the [awesome-surreal](https://github.com/surrealdb/awesome-surreal) repository. To add more projects to the list, simply open a pull-request!
We absolutely agree! We dont currently have ORM support in the drivers themselves, and arent likely to implement this, as there are many ORM libraries and integrations with which to integrate. We are, however, very excited to discover what the community creates. We encourage both newcomers and existing members to explore various projects that address their needs - these can be found in the [awesome-surreal](https://github.com/surrealdb/awesome-surreal) repository. To add more projects to the list, simply open a pull-request!
### Do you support language X?

View file

@ -1,6 +1,5 @@
use crate::cf::{TableMutation, TableMutations};
use crate::kvs::Key;
use crate::sql::ident::Ident;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use std::borrow::Cow;
@ -59,16 +58,16 @@ impl Writer {
}
}
pub(crate) fn update(&mut self, ns: &str, db: &str, tb: Ident, id: Thing, v: Cow<'_, Value>) {
pub(crate) fn update(&mut self, ns: &str, db: &str, tb: &str, id: Thing, v: Cow<'_, Value>) {
if v.is_some() {
self.buf.push(
ns.to_string(),
db.to_string(),
tb.0,
tb.to_string(),
TableMutation::Set(id, v.into_owned()),
);
} else {
self.buf.push(ns.to_string(), db.to_string(), tb.0, TableMutation::Del(id));
self.buf.push(ns.to_string(), db.to_string(), tb.to_string(), TableMutation::Del(id));
}
}
@ -118,16 +117,16 @@ mod tests {
let ts = crate::sql::Datetime::default();
let ns = "myns";
let db = "mydb";
let tb = super::Ident("mytb".to_string());
let tb = "mytb";
let mut dns = DefineNamespaceStatement::default();
dns.name = super::Ident(ns.to_string());
dns.name = crate::sql::Ident(ns.to_string());
let mut ddb = DefineDatabaseStatement::default();
ddb.name = super::Ident(db.to_string());
ddb.name = crate::sql::Ident(db.to_string());
ddb.changefeed = Some(ChangeFeed {
expiry: Duration::from_secs(10),
});
let mut dtb = DefineTableStatement::default();
dtb.name = tb.clone();
dtb.name = tb.into();
dtb.changefeed = Some(ChangeFeed {
expiry: Duration::from_secs(10),
});
@ -156,38 +155,38 @@ mod tests {
let mut tx1 = ds.transaction(true, false).await.unwrap();
let thing_a = Thing {
tb: tb.clone().0,
tb: tb.to_owned(),
id: Id::String("A".to_string()),
};
let value_a: super::Value = "a".into();
tx1.record_change(ns, db, &dtb, &thing_a, Cow::Borrowed(&value_a));
tx1.record_change(ns, db, tb, &thing_a, Cow::Borrowed(&value_a));
tx1.complete_changes(true).await.unwrap();
let _r1 = tx1.commit().await.unwrap();
let mut tx2 = ds.transaction(true, false).await.unwrap();
let thing_c = Thing {
tb: tb.clone().0,
tb: tb.to_owned(),
id: Id::String("C".to_string()),
};
let value_c: Value = "c".into();
tx2.record_change(ns, db, &dtb, &thing_c, Cow::Borrowed(&value_c));
tx2.record_change(ns, db, tb, &thing_c, Cow::Borrowed(&value_c));
tx2.complete_changes(true).await.unwrap();
let _r2 = tx2.commit().await.unwrap();
let x = ds.transaction(true, false).await;
let mut tx3 = x.unwrap();
let thing_b = Thing {
tb: tb.clone().0,
tb: tb.to_owned(),
id: Id::String("B".to_string()),
};
let value_b: Value = "b".into();
tx3.record_change(ns, db, &dtb, &thing_b, Cow::Borrowed(&value_b));
tx3.record_change(ns, db, tb, &thing_b, Cow::Borrowed(&value_b));
let thing_c2 = Thing {
tb: tb.clone().0,
tb: tb.to_owned(),
id: Id::String("C".to_string()),
};
let value_c2: Value = "c2".into();
tx3.record_change(ns, db, &dtb, &thing_c2, Cow::Borrowed(&value_c2));
tx3.record_change(ns, db, tb, &thing_c2, Cow::Borrowed(&value_c2));
tx3.complete_changes(true).await.unwrap();
tx3.commit().await.unwrap();
@ -199,16 +198,10 @@ mod tests {
let mut tx4 = ds.transaction(true, false).await.unwrap();
let tb = tb.clone();
let r = crate::cf::read(
&mut tx4,
ns,
db,
Some(tb.0.as_ref()),
ShowSince::Versionstamp(start),
Some(10),
)
.await
.unwrap();
let r =
crate::cf::read(&mut tx4, ns, db, Some(tb), ShowSince::Versionstamp(start), Some(10))
.await
.unwrap();
tx4.commit().await.unwrap();
let mut want: Vec<ChangeSet> = Vec::new();
@ -260,16 +253,10 @@ mod tests {
// Now we should see the gc_all results
let mut tx6 = ds.transaction(true, false).await.unwrap();
let tb = tb.clone();
let r = crate::cf::read(
&mut tx6,
ns,
db,
Some(tb.0.as_ref()),
ShowSince::Versionstamp(start),
Some(10),
)
.await
.unwrap();
let r =
crate::cf::read(&mut tx6, ns, db, Some(tb), ShowSince::Versionstamp(start), Some(10))
.await
.unwrap();
tx6.commit().await.unwrap();
let mut want: Vec<ChangeSet> = Vec::new();
@ -295,16 +282,9 @@ mod tests {
ds.tick_at((ts.0.timestamp() + 5).try_into().unwrap()).await.unwrap();
let mut tx7 = ds.transaction(true, false).await.unwrap();
let r = crate::cf::read(
&mut tx7,
ns,
db,
Some(tb.0.as_ref()),
ShowSince::Timestamp(ts),
Some(10),
)
.await
.unwrap();
let r = crate::cf::read(&mut tx7, ns, db, Some(tb), ShowSince::Timestamp(ts), Some(10))
.await
.unwrap();
tx7.commit().await.unwrap();
assert_eq!(r, want);
}

View file

@ -61,10 +61,7 @@ impl<'a> Executor<'a> {
}
/// Commits the transaction if it is local.
/// This function takes two additional parameters that are not present in the underlying kvs::Transaction::commit() function:
/// ns: The namespace of the transaction
/// db: The database of the transaction
/// These parameters are used updating the changefeed.
///
/// # Return
///
/// An `Err` if the transaction could not be commited;

View file

@ -6,6 +6,7 @@ use crate::iam::{Action, Auth, ResourceKind, Role};
use crate::sql::Base;
use channel::Sender;
use std::sync::Arc;
use uuid::Uuid;
/// An Options is passed around when processing a set of query
/// statements. An Options contains specific information for how
@ -16,7 +17,7 @@ use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct Options {
/// Current Node ID
id: Option<uuid::Uuid>,
id: Option<Uuid>,
/// Currently selected NS
ns: Option<Arc<str>>,
/// Currently selected DB
@ -119,7 +120,7 @@ impl Options {
/// Set the Node ID for subsequent code which uses
/// this `Options`, with support for chaining.
pub fn with_id(mut self, id: uuid::Uuid) -> Self {
pub fn with_id(mut self, id: Uuid) -> Self {
self.id = Some(id);
self
}
@ -407,7 +408,7 @@ impl Options {
// --------------------------------------------------
/// Get current Node ID
pub fn id(&self) -> Result<uuid::Uuid, Error> {
pub fn id(&self) -> Result<Uuid, Error> {
self.id.ok_or(Error::Unreachable)
}

View file

@ -13,24 +13,25 @@ impl<'a> Document<'a> {
txn: &Transaction,
_stm: &Statement<'_>,
) -> Result<(), Error> {
// Check if forced
if !opt.force && !self.changed() {
// Check if changed
if !self.changed() {
return Ok(());
}
// Get the record id
let _ = self.id.as_ref().unwrap();
let ns = opt.ns();
let db = opt.db();
// Get the table for the record
let tb = self.tb(opt, txn).await?;
let tb = tb.as_ref();
// Check if changefeeds are enabled
if tb.changefeed.is_some() {
// Clone transaction
let txn = txn.clone();
let mut txn = txn.lock().await;
let id = &(*self.id.as_ref().unwrap()).clone();
let run = txn.clone();
// Claim transaction
let mut run = run.lock().await;
// Get the arguments
let ns = opt.ns();
let db = opt.db();
let tb = tb.name.as_str();
let id = self.id.as_ref().unwrap();
// Create the changefeed entry
txn.record_change(ns, db, tb, id, self.current.doc.clone());
run.record_change(ns, db, tb, id, self.current.doc.clone());
}
// Carry on
Ok(())

View file

@ -150,7 +150,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the table definitions
txn.clone().lock().await.all_ft(opt.ns(), opt.db(), &id.tb).await
txn.clone().lock().await.all_tb_views(opt.ns(), opt.db(), &id.tb).await
}
/// Get the events for this document
pub async fn ev(
@ -161,7 +161,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the event definitions
txn.clone().lock().await.all_ev(opt.ns(), opt.db(), &id.tb).await
txn.clone().lock().await.all_tb_events(opt.ns(), opt.db(), &id.tb).await
}
/// Get the fields for this document
pub async fn fd(
@ -172,7 +172,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the field definitions
txn.clone().lock().await.all_fd(opt.ns(), opt.db(), &id.tb).await
txn.clone().lock().await.all_tb_fields(opt.ns(), opt.db(), &id.tb).await
}
/// Get the indexes for this document
pub async fn ix(
@ -183,7 +183,7 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the index definitions
txn.clone().lock().await.all_ix(opt.ns(), opt.db(), &id.tb).await
txn.clone().lock().await.all_tb_indexes(opt.ns(), opt.db(), &id.tb).await
}
// Get the lives for this document
pub async fn lv(
@ -194,6 +194,6 @@ impl<'a> Document<'a> {
// Get the record id
let id = self.id.as_ref().unwrap();
// Get the table definition
txn.clone().lock().await.all_lv(opt.ns(), opt.db(), &id.tb).await
txn.clone().lock().await.all_tb_lives(opt.ns(), opt.db(), &id.tb).await
}
}

View file

@ -125,8 +125,18 @@ impl<'a> Document<'a> {
};
// Match the permission clause
match perms {
// The field PERMISSIONS clause
// is FULL, enabling this field
// to be updated without checks.
Permission::Full => (),
// The field PERMISSIONS clause
// is NONE, meaning that this
// change will be reverted.
Permission::None => val = old,
// The field PERMISSIONS clause
// is a custom expression, so
// we check the expression and
// revert the field if denied.
Permission::Specific(e) => {
// Disable permissions
let opt = &opt.new_with_perms(false);

View file

@ -337,7 +337,7 @@ impl<'a> IndexOperation<'a> {
p: &SearchParams,
) -> Result<(), Error> {
let ikb = IndexKeyBase::new(self.opt, self.ix);
let az = run.get_az(self.opt.ns(), self.opt.db(), p.az.as_str()).await?;
let az = run.get_db_analyzer(self.opt.ns(), self.opt.db(), p.az.as_str()).await?;
let mut ft = FtIndex::new(run, az, ikb, p, TreeStoreType::Write).await?;
if let Some(n) = &self.n {
ft.index_document(run, self.rid, n).await?;

View file

@ -1,5 +1,4 @@
use super::classes;
use crate::sql::number::decimal_is_integer;
use crate::sql::number::Number;
use crate::sql::value::Value;
use js::Array;
@ -26,7 +25,7 @@ impl<'js> IntoJs<'js> for &Value {
Value::Strand(v) => js::String::from_str(ctx.clone(), v)?.into_js(ctx),
Value::Number(Number::Int(v)) => Ok(js::Value::new_int(ctx.clone(), *v as i32)),
Value::Number(Number::Float(v)) => Ok(js::Value::new_float(ctx.clone(), *v)),
&Value::Number(Number::Decimal(v)) => match decimal_is_integer(&v) {
&Value::Number(Number::Decimal(v)) => match v.is_integer() {
true => Ok(js::Value::new_int(ctx.clone(), v.try_into().unwrap_or_default())),
false => Ok(js::Value::new_float(ctx.clone(), v.try_into().unwrap_or_default())),
},

View file

@ -159,7 +159,7 @@ pub async fn token(kvs: &Datastore, session: &mut Session, token: &str) -> Resul
None => Value::None,
};
// Get the scope token
let de = tx.get_st(&ns, &db, &sc, &tk).await?;
let de = tx.get_sc_token(&ns, &db, &sc, &tk).await?;
let cf = config(de.kind, de.code)?;
// Verify the token
decode::<Claims>(token, &cf.0, &cf.1)?;
@ -224,7 +224,7 @@ pub async fn token(kvs: &Datastore, session: &mut Session, token: &str) -> Resul
// Create a new readonly transaction
let mut tx = kvs.transaction(false, false).await?;
// Get the database token
let de = tx.get_dt(&ns, &db, &tk).await?;
let de = tx.get_db_token(&ns, &db, &tk).await?;
let cf = config(de.kind, de.code)?;
// Verify the token
decode::<Claims>(token, &cf.0, &cf.1)?;
@ -293,7 +293,7 @@ pub async fn token(kvs: &Datastore, session: &mut Session, token: &str) -> Resul
// Create a new readonly transaction
let mut tx = kvs.transaction(false, false).await?;
// Get the namespace token
let de = tx.get_nt(&ns, &tk).await?;
let de = tx.get_ns_token(&ns, &tk).await?;
let cf = config(de.kind, de.code)?;
// Verify the token
decode::<Claims>(token, &cf.0, &cf.1)?;

View file

@ -55,7 +55,7 @@ impl QueryExecutor {
}
} else {
let ikb = IndexKeyBase::new(opt, io.ix());
let az = run.get_az(opt.ns(), opt.db(), p.az.as_str()).await?;
let az = run.get_db_analyzer(opt.ns(), opt.db(), p.az.as_str()).await?;
let ft = FtIndex::new(&mut run, az, ikb, p, TreeStoreType::Read).await?;
let ixn = ixn.to_owned();
if entry.is_none() {

View file

@ -54,7 +54,7 @@ impl<'a> TreeBuilder<'a> {
.clone()
.lock()
.await
.all_ix(self.opt.ns(), self.opt.db(), &self.table.0)
.all_tb_indexes(self.opt.ns(), self.opt.db(), &self.table.0)
.await?;
self.indexes = Some(indexes);
}

View file

@ -20,7 +20,10 @@ use std::sync::Arc;
pub enum Entry {
// Single definitions
Db(Arc<DefineDatabaseStatement>),
Fc(Arc<DefineFunctionStatement>),
Ix(Arc<DefineIndexStatement>),
Ns(Arc<DefineNamespaceStatement>),
Pa(Arc<DefineParamStatement>),
Tb(Arc<DefineTableStatement>),
// Multi definitions
Azs(Arc<[DefineAnalyzerStatement]>),
@ -38,9 +41,10 @@ pub enum Entry {
Nus(Arc<[DefineUserStatement]>),
Pas(Arc<[DefineParamStatement]>),
Scs(Arc<[DefineScopeStatement]>),
Seq(U32),
Sts(Arc<[DefineTokenStatement]>),
Tbs(Arc<[DefineTableStatement]>),
// Sequences
Seq(U32),
}
#[derive(Default)]

View file

@ -311,7 +311,7 @@ impl Datastore {
let stm = DefineUserStatement::from((Base::Root, creds.username, creds.password));
let ctx = Context::default();
let opt = Options::new().with_auth(Arc::new(Auth::for_root(Role::Owner)));
let _result = stm.compute(&ctx, &opt, &txn, None).await?;
let _ = stm.compute(&ctx, &opt, &txn, None).await?;
txn.lock().await.commit().await?;
Ok(())
}
@ -541,7 +541,8 @@ impl Datastore {
trace!("Archiving lqs and found {} LQ entries for {}", lqs.len(), nd);
let mut ret = vec![];
for lq in lqs {
let lvs = tx.get_lv(lq.ns.as_str(), lq.db.as_str(), lq.tb.as_str(), &lq.lq).await?;
let lvs =
tx.get_tb_live(lq.ns.as_str(), lq.db.as_str(), lq.tb.as_str(), &lq.lq).await?;
let archived_lvs = lvs.clone().archive(this_node_id.clone());
tx.putc_tblq(&lq.ns, &lq.db, &lq.tb, archived_lvs, Some(lvs)).await?;
ret.push(lq);

View file

@ -104,8 +104,10 @@ async fn expired_nodes_get_live_queries_archived() {
// Now validate lq was removed
let mut tx = test.db.transaction(true, false).await.unwrap();
let scanned =
tx.all_lv(ses.ns().unwrap().as_ref(), ses.db().unwrap().as_ref(), table).await.unwrap();
let scanned = tx
.all_tb_lives(ses.ns().unwrap().as_ref(), ses.db().unwrap().as_ref(), table)
.await
.unwrap();
assert_eq!(scanned.len(), 0);
tx.commit().await.unwrap();
}
@ -180,7 +182,7 @@ async fn single_live_queries_are_garbage_collected() {
// Validate
trace!("Validating live queries");
let mut tx = test.db.transaction(true, false).await.unwrap();
let scanned = tx.all_lv(namespace, database, table).await.unwrap();
let scanned = tx.all_tb_lives(namespace, database, table).await.unwrap();
assert_eq!(scanned.len(), 1, "The scanned values are {:?}", scanned);
assert_eq!(&scanned[0].id.0, &live_query_to_keep);
let scanned = tx.all_lq(&node_id).await.unwrap();

View file

@ -46,7 +46,7 @@ async fn archive_lv_for_node_archives() {
tx.commit().await.unwrap();
let mut tx = test.db.transaction(true, false).await.unwrap();
let lv = tx.all_lv(namespace, database, table).await.unwrap();
let lv = tx.all_tb_lives(namespace, database, table).await.unwrap();
assert_eq!(lv.len(), 1, "{:?}", lv);
assert_eq!(lv[0].archived, Some(this_node_id));
tx.commit().await.unwrap();

View file

@ -617,12 +617,7 @@ impl Transaction {
K: Into<Key> + Debug + Clone,
{
#[cfg(debug_assertions)]
trace!(
"Scan {:?} - {:?}",
crate::key::debug::sprint_key(&(rng.start).clone().into()),
crate::key::debug::sprint_key(&(rng.end).clone().into()),
// rng.start, rng.end);
);
trace!("Scan {:?} - {:?}", rng.start, rng.end);
match self {
#[cfg(feature = "kv-mem")]
Transaction {
@ -758,16 +753,12 @@ impl Transaction {
/// This function fetches key-value pairs from the underlying datastore in batches of 1000.
pub async fn getr<K>(&mut self, rng: Range<K>, limit: u32) -> Result<Vec<(Key, Val)>, Error>
where
K: Into<Key> + Debug + Clone,
K: Into<Key> + Debug,
{
#[cfg(debug_assertions)]
trace!("Getr {:?}..{:?} (limit: {limit})", rng.start, rng.end);
let beg: Key = rng.start.into();
let end: Key = rng.end.into();
trace!(
"Getr {:?}..{:?} (limit: {})",
crate::key::debug::sprint_key(&beg),
crate::key::debug::sprint_key(&end),
limit
);
let mut nxt: Option<Key> = None;
let mut num = limit;
let mut out: Vec<(Key, Val)> = vec![];
@ -815,8 +806,10 @@ impl Transaction {
/// This function fetches key-value pairs from the underlying datastore in batches of 1000.
pub async fn delr<K>(&mut self, rng: Range<K>, limit: u32) -> Result<(), Error>
where
K: Into<Key>,
K: Into<Key> + Debug,
{
#[cfg(debug_assertions)]
trace!("Delr {:?}..{:?} (limit: {limit})", rng.start, rng.end);
let beg: Key = rng.start.into();
let end: Key = rng.end.into();
let mut nxt: Option<Key> = None;
@ -864,8 +857,10 @@ impl Transaction {
/// This function fetches key-value pairs from the underlying datastore in batches of 1000.
pub async fn getp<K>(&mut self, key: K, limit: u32) -> Result<Vec<(Key, Val)>, Error>
where
K: Into<Key>,
K: Into<Key> + Debug,
{
#[cfg(debug_assertions)]
trace!("Getp {:?} (limit: {limit})", key);
let beg: Key = key.into();
let end: Key = beg.clone().add(0xff);
let mut nxt: Option<Key> = None;
@ -914,8 +909,10 @@ impl Transaction {
/// This function fetches key-value pairs from the underlying datastore in batches of 1000.
pub async fn delp<K>(&mut self, key: K, limit: u32) -> Result<(), Error>
where
K: Into<Key>,
K: Into<Key> + Debug,
{
#[cfg(debug_assertions)]
trace!("Delp {:?} (limit: {limit})", key);
let beg: Key = key.into();
let end: Key = beg.clone().add(0xff);
let mut nxt: Option<Key> = None;
@ -1180,11 +1177,11 @@ impl Transaction {
let tb: String = String::from_utf8(value).unwrap();
trace!("scan_lq Found tb: {:?}", tb);
res.push(LqValue {
nd: crate::sql::uuid::Uuid::from(lq.nd),
nd: lq.nd.into(),
ns: lq.ns.to_string(),
db: lq.db.to_string(),
tb,
lq: crate::sql::uuid::Uuid::from(lq.lq),
lq: lq.lq.into(),
});
}
Ok(res)
@ -1236,6 +1233,15 @@ impl Transaction {
self.putc(key_enc, live_stm, expected).await
}
/// Retrieve all ROOT users.
pub async fn all_root_users(&mut self) -> Result<Arc<[DefineUserStatement]>, Error> {
let beg = crate::key::root::us::prefix();
let end = crate::key::root::us::suffix();
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
Ok(val)
}
/// Retrieve all namespace definitions in a datastore.
pub async fn all_ns(&mut self) -> Result<Arc<[DefineNamespaceStatement]>, Error> {
let key = crate::key::root::ns::prefix();
@ -1275,7 +1281,7 @@ impl Transaction {
}
/// Retrieve all namespace token definitions for a specific namespace.
pub async fn all_nt(&mut self, ns: &str) -> Result<Arc<[DefineTokenStatement]>, Error> {
pub async fn all_ns_tokens(&mut self, ns: &str) -> Result<Arc<[DefineTokenStatement]>, Error> {
let key = crate::key::namespace::tk::prefix(ns);
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Nts(v) = e {
@ -1336,7 +1342,7 @@ impl Transaction {
}
/// Retrieve all database token definitions for a specific database.
pub async fn all_dt(
pub async fn all_db_tokens(
&mut self,
ns: &str,
db: &str,
@ -1358,8 +1364,31 @@ impl Transaction {
})
}
/// Retrieve all analyzer definitions for a specific database.
pub async fn all_db_analyzers(
&mut self,
ns: &str,
db: &str,
) -> Result<Arc<[DefineAnalyzerStatement]>, Error> {
let key = crate::key::database::az::prefix(ns, db);
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Azs(v) = e {
v
} else {
unreachable!();
}
} else {
let beg = crate::key::database::az::prefix(ns, db);
let end = crate::key::database::az::suffix(ns, db);
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
self.cache.set(key, Entry::Azs(Arc::clone(&val)));
val
})
}
/// Retrieve all function definitions for a specific database.
pub async fn all_fc(
pub async fn all_db_functions(
&mut self,
ns: &str,
db: &str,
@ -1381,6 +1410,29 @@ impl Transaction {
})
}
/// Retrieve all param definitions for a specific database.
pub async fn all_db_params(
&mut self,
ns: &str,
db: &str,
) -> Result<Arc<[DefineParamStatement]>, Error> {
let key = crate::key::database::pa::prefix(ns, db);
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Pas(v) = e {
v
} else {
unreachable!();
}
} else {
let beg = crate::key::database::pa::prefix(ns, db);
let end = crate::key::database::pa::suffix(ns, db);
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
self.cache.set(key, Entry::Pas(Arc::clone(&val)));
val
})
}
/// Retrieve all scope definitions for a specific database.
pub async fn all_sc(
&mut self,
@ -1405,7 +1457,7 @@ impl Transaction {
}
/// Retrieve all scope token definitions for a scope.
pub async fn all_st(
pub async fn all_sc_tokens(
&mut self,
ns: &str,
db: &str,
@ -1428,29 +1480,6 @@ impl Transaction {
})
}
/// Retrieve all param definitions for a specific database.
pub async fn all_pa(
&mut self,
ns: &str,
db: &str,
) -> Result<Arc<[DefineParamStatement]>, Error> {
let key = crate::key::database::pa::prefix(ns, db);
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Pas(v) = e {
v
} else {
unreachable!();
}
} else {
let beg = crate::key::database::pa::prefix(ns, db);
let end = crate::key::database::pa::suffix(ns, db);
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
self.cache.set(key, Entry::Pas(Arc::clone(&val)));
val
})
}
/// Retrieve all table definitions for a specific database.
pub async fn all_tb(
&mut self,
@ -1475,7 +1504,7 @@ impl Transaction {
}
/// Retrieve all event definitions for a specific table.
pub async fn all_ev(
pub async fn all_tb_events(
&mut self,
ns: &str,
db: &str,
@ -1499,7 +1528,7 @@ impl Transaction {
}
/// Retrieve all field definitions for a specific table.
pub async fn all_fd(
pub async fn all_tb_fields(
&mut self,
ns: &str,
db: &str,
@ -1523,7 +1552,7 @@ impl Transaction {
}
/// Retrieve all index definitions for a specific table.
pub async fn all_ix(
pub async fn all_tb_indexes(
&mut self,
ns: &str,
db: &str,
@ -1547,7 +1576,7 @@ impl Transaction {
}
/// Retrieve all view definitions for a specific table.
pub async fn all_ft(
pub async fn all_tb_views(
&mut self,
ns: &str,
db: &str,
@ -1571,7 +1600,7 @@ impl Transaction {
}
/// Retrieve all live definitions for a specific table.
pub async fn all_lv(
pub async fn all_tb_lives(
&mut self,
ns: &str,
db: &str,
@ -1606,48 +1635,24 @@ impl Transaction {
Error::Internal(format!("Failed to decode a value while reading LQ: {}", e))
})?;
let lqv = LqValue {
nd: crate::sql::uuid::Uuid::from(*nd),
nd: (*nd).into(),
ns: lq_key.ns.to_string(),
db: lq_key.db.to_string(),
tb: lq_value,
lq: crate::sql::uuid::Uuid::from(lq_key.lq),
lq: lq_key.lq.into(),
};
lqs.push(lqv);
}
Ok(lqs)
}
/// Retrieve all analyzer definitions for a specific database.
pub async fn all_az(
&mut self,
ns: &str,
db: &str,
) -> Result<Arc<[DefineAnalyzerStatement]>, Error> {
let key = crate::key::database::az::prefix(ns, db);
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Azs(v) = e {
v
} else {
unreachable!();
}
} else {
let beg = crate::key::database::az::prefix(ns, db);
let end = crate::key::database::az::suffix(ns, db);
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
self.cache.set(key, Entry::Azs(Arc::clone(&val)));
val
})
}
/// Retrieve all ROOT users.
pub async fn all_root_users(&mut self) -> Result<Arc<[DefineUserStatement]>, Error> {
let beg = crate::key::root::us::prefix();
let end = crate::key::root::us::suffix();
let val = self.getr(beg..end, u32::MAX).await?;
let val = val.convert().into();
Ok(val)
/// Retrieve a specific user definition from ROOT.
pub async fn get_root_user(&mut self, user: &str) -> Result<DefineUserStatement, Error> {
let key = crate::key::root::us::new(user);
let val = self.get(key).await?.ok_or(Error::UserRootNotFound {
value: user.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific namespace definition.
@ -1659,8 +1664,26 @@ impl Transaction {
Ok(val.into())
}
/// Retrieve a specific user definition from a namespace.
pub async fn get_ns_user(
&mut self,
ns: &str,
user: &str,
) -> Result<DefineUserStatement, Error> {
let key = crate::key::namespace::us::new(ns, user);
let val = self.get(key).await?.ok_or(Error::UserNsNotFound {
value: user.to_owned(),
ns: ns.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific namespace token definition.
pub async fn get_nt(&mut self, ns: &str, nt: &str) -> Result<DefineTokenStatement, Error> {
pub async fn get_ns_token(
&mut self,
ns: &str,
nt: &str,
) -> Result<DefineTokenStatement, Error> {
let key = crate::key::namespace::tk::new(ns, nt);
let val = self.get(key).await?.ok_or(Error::NtNotFound {
value: nt.to_owned(),
@ -1677,8 +1700,24 @@ impl Transaction {
Ok(val.into())
}
/// Retrieve a specific user definition from a database.
pub async fn get_db_user(
&mut self,
ns: &str,
db: &str,
user: &str,
) -> Result<DefineUserStatement, Error> {
let key = crate::key::database::us::new(ns, db, user);
let val = self.get(key).await?.ok_or(Error::UserDbNotFound {
value: user.to_owned(),
ns: ns.to_owned(),
db: db.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific database token definition.
pub async fn get_dt(
pub async fn get_db_token(
&mut self,
ns: &str,
db: &str,
@ -1691,6 +1730,20 @@ impl Transaction {
Ok(val.into())
}
/// Retrieve a specific analyzer definition.
pub async fn get_db_analyzer(
&mut self,
ns: &str,
db: &str,
az: &str,
) -> Result<DefineAnalyzerStatement, Error> {
let key = crate::key::database::az::new(ns, db, az);
let val = self.get(key).await?.ok_or(Error::AzNotFound {
value: az.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific scope definition.
pub async fn get_sc(
&mut self,
@ -1706,7 +1759,7 @@ impl Transaction {
}
/// Retrieve a specific scope token definition.
pub async fn get_st(
pub async fn get_sc_token(
&mut self,
ns: &str,
db: &str,
@ -1720,20 +1773,6 @@ impl Transaction {
Ok(val.into())
}
/// Retrieve a specific function definition.
pub async fn get_fc(
&mut self,
ns: &str,
db: &str,
fc: &str,
) -> Result<DefineFunctionStatement, Error> {
let key = crate::key::database::fc::new(ns, db, fc);
let val = self.get(key).await?.ok_or(Error::FcNotFound {
value: fc.to_owned(),
})?;
Ok(val.into())
}
/// Return the table stored at the lq address
pub async fn get_lq(
&mut self,
@ -1749,36 +1788,6 @@ impl Transaction {
Value::from(val).convert_to_strand()
}
pub async fn get_lv(
&mut self,
ns: &str,
db: &str,
tb: &str,
lv: &Uuid,
) -> Result<LiveStatement, Error> {
let key = crate::key::table::lq::new(ns, db, tb, *lv);
let key_enc = crate::key::table::lq::Lq::encode(&key)?;
trace!("Getting lv ({:?}) {:?}", lv, crate::key::debug::sprint_key(&key_enc));
let val = self.get(key_enc).await?.ok_or(Error::LvNotFound {
value: lv.to_string(),
})?;
Ok(val.into())
}
/// Retrieve a specific param definition.
pub async fn get_pa(
&mut self,
ns: &str,
db: &str,
pa: &str,
) -> Result<DefineParamStatement, Error> {
let key = crate::key::database::pa::new(ns, db, pa);
let val = self.get(key).await?.ok_or(Error::PaNotFound {
value: pa.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific table definition.
pub async fn get_tb(
&mut self,
@ -1792,69 +1801,20 @@ impl Transaction {
})?;
Ok(val.into())
}
/// Retrieve a specific analyzer definition.
pub async fn get_az(
&mut self,
ns: &str,
db: &str,
az: &str,
) -> Result<DefineAnalyzerStatement, Error> {
let key = crate::key::database::az::new(ns, db, az);
let val = self.get(key).await?.ok_or(Error::AzNotFound {
value: az.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific analyzer definition.
pub async fn get_ix(
/// Retrieve a live query for a table.
pub async fn get_tb_live(
&mut self,
ns: &str,
db: &str,
tb: &str,
ix: &str,
) -> Result<DefineIndexStatement, Error> {
let key = crate::key::table::ix::new(ns, db, tb, ix);
let val = self.get(key).await?.ok_or(Error::IxNotFound {
value: ix.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific user definition from ROOT.
pub async fn get_root_user(&mut self, user: &str) -> Result<DefineUserStatement, Error> {
let key = crate::key::root::us::new(user);
let val = self.get(key).await?.ok_or(Error::UserRootNotFound {
value: user.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific user definition from a namespace.
pub async fn get_ns_user(
&mut self,
ns: &str,
user: &str,
) -> Result<DefineUserStatement, Error> {
let key = crate::key::namespace::us::new(ns, user);
let val = self.get(key).await?.ok_or(Error::UserNsNotFound {
value: user.to_owned(),
ns: ns.to_owned(),
})?;
Ok(val.into())
}
/// Retrieve a specific user definition from a database.
pub async fn get_db_user(
&mut self,
ns: &str,
db: &str,
user: &str,
) -> Result<DefineUserStatement, Error> {
let key = crate::key::database::us::new(ns, db, user);
let val = self.get(key).await?.ok_or(Error::UserDbNotFound {
value: user.to_owned(),
ns: ns.to_owned(),
db: db.to_owned(),
lv: &Uuid,
) -> Result<LiveStatement, Error> {
let key = crate::key::table::lq::new(ns, db, tb, *lv);
let key_enc = crate::key::table::lq::Lq::encode(&key)?;
trace!("Getting lv ({:?}) {:?}", lv, crate::key::debug::sprint_key(&key_enc));
let val = self.get(key_enc).await?.ok_or(Error::LvNotFound {
value: lv.to_string(),
})?;
Ok(val.into())
}
@ -2046,6 +2006,79 @@ impl Transaction {
})
}
/// Retrieve a specific function definition.
pub async fn get_and_cache_db_function(
&mut self,
ns: &str,
db: &str,
fc: &str,
) -> Result<Arc<DefineFunctionStatement>, Error> {
let key = crate::key::database::fc::new(ns, db, fc).encode()?;
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Fc(v) = e {
v
} else {
unreachable!();
}
} else {
let val = self.get(key.clone()).await?.ok_or(Error::FcNotFound {
value: fc.to_owned(),
})?;
let val: Arc<DefineFunctionStatement> = Arc::new(val.into());
self.cache.set(key, Entry::Fc(Arc::clone(&val)));
val
})
}
/// Retrieve a specific param definition.
pub async fn get_and_cache_db_param(
&mut self,
ns: &str,
db: &str,
pa: &str,
) -> Result<Arc<DefineParamStatement>, Error> {
let key = crate::key::database::pa::new(ns, db, pa).encode()?;
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Pa(v) = e {
v
} else {
unreachable!();
}
} else {
let val = self.get(key.clone()).await?.ok_or(Error::PaNotFound {
value: pa.to_owned(),
})?;
let val: Arc<DefineParamStatement> = Arc::new(val.into());
self.cache.set(key, Entry::Pa(Arc::clone(&val)));
val
})
}
/// Retrieve a specific table index definition.
pub async fn get_and_cache_tb_index(
&mut self,
ns: &str,
db: &str,
tb: &str,
ix: &str,
) -> Result<Arc<DefineIndexStatement>, Error> {
let key = crate::key::table::ix::new(ns, db, tb, ix).encode()?;
Ok(if let Some(e) = self.cache.get(&key) {
if let Entry::Ix(v) = e {
v
} else {
unreachable!();
}
} else {
let val = self.get(key.clone()).await?.ok_or(Error::IxNotFound {
value: ix.to_owned(),
})?;
let val: Arc<DefineIndexStatement> = Arc::new(val.into());
self.cache.set(key, Entry::Ix(Arc::clone(&val)));
val
})
}
/// Add a namespace with a default configuration, only if we are in dynamic mode.
pub async fn add_and_cache_ns(
&mut self,
@ -2170,20 +2203,6 @@ impl Transaction {
chn.send(bytes!("OPTION IMPORT;")).await?;
chn.send(bytes!("")).await?;
}
// Output FUNCTIONS
{
let fcs = self.all_fc(ns, db).await?;
if !fcs.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- FUNCTIONS")).await?;
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("")).await?;
for fc in fcs.iter() {
chn.send(bytes!(format!("{fc};"))).await?;
}
chn.send(bytes!("")).await?;
}
}
// Output USERS
{
let dus = self.all_db_users(ns, db).await?;
@ -2200,7 +2219,7 @@ impl Transaction {
}
// Output TOKENS
{
let dts = self.all_dt(ns, db).await?;
let dts = self.all_db_tokens(ns, db).await?;
if !dts.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- TOKENS")).await?;
@ -2214,7 +2233,7 @@ impl Transaction {
}
// Output PARAMS
{
let pas = self.all_pa(ns, db).await?;
let pas = self.all_db_params(ns, db).await?;
if !pas.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- PARAMS")).await?;
@ -2226,6 +2245,34 @@ impl Transaction {
chn.send(bytes!("")).await?;
}
}
// Output FUNCTIONS
{
let fcs = self.all_db_functions(ns, db).await?;
if !fcs.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- FUNCTIONS")).await?;
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("")).await?;
for fc in fcs.iter() {
chn.send(bytes!(format!("{fc};"))).await?;
}
chn.send(bytes!("")).await?;
}
}
// Output ANALYZERS
{
let azs = self.all_db_analyzers(ns, db).await?;
if !azs.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- ANALYZERS")).await?;
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("")).await?;
for az in azs.iter() {
chn.send(bytes!(format!("{az};"))).await?;
}
chn.send(bytes!("")).await?;
}
}
// Output SCOPES
{
let scs = self.all_sc(ns, db).await?;
@ -2239,7 +2286,7 @@ impl Transaction {
chn.send(bytes!(format!("{sc};"))).await?;
// Output TOKENS
{
let sts = self.all_st(ns, db, &sc.name).await?;
let sts = self.all_sc_tokens(ns, db, &sc.name).await?;
if !sts.is_empty() {
for st in sts.iter() {
chn.send(bytes!(format!("{st};"))).await?;
@ -2251,20 +2298,6 @@ impl Transaction {
chn.send(bytes!("")).await?;
}
}
// Output ANALYZERS
{
let azs = self.all_az(ns, db).await?;
if !azs.is_empty() {
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("-- ANALYZERS")).await?;
chn.send(bytes!("-- ------------------------------")).await?;
chn.send(bytes!("")).await?;
for az in azs.iter() {
chn.send(bytes!(format!("{az};"))).await?;
}
chn.send(bytes!("")).await?;
}
}
// Output TABLES
{
let tbs = self.all_tb(ns, db).await?;
@ -2278,17 +2311,15 @@ impl Transaction {
chn.send(bytes!(format!("{tb};"))).await?;
chn.send(bytes!("")).await?;
// Output FIELDS
{
let fds = self.all_fd(ns, db, &tb.name).await?;
if !fds.is_empty() {
for fd in fds.iter() {
chn.send(bytes!(format!("{fd};"))).await?;
}
chn.send(bytes!("")).await?;
let fds = self.all_tb_fields(ns, db, &tb.name).await?;
if !fds.is_empty() {
for fd in fds.iter() {
chn.send(bytes!(format!("{fd};"))).await?;
}
chn.send(bytes!("")).await?;
}
// Output INDEXES
let ixs = self.all_ix(ns, db, &tb.name).await?;
let ixs = self.all_tb_indexes(ns, db, &tb.name).await?;
if !ixs.is_empty() {
for ix in ixs.iter() {
chn.send(bytes!(format!("{ix};"))).await?;
@ -2296,7 +2327,7 @@ impl Transaction {
chn.send(bytes!("")).await?;
}
// Output EVENTS
let evs = self.all_ev(ns, db, &tb.name).await?;
let evs = self.all_tb_events(ns, db, &tb.name).await?;
if !evs.is_empty() {
for ev in evs.iter() {
chn.send(bytes!(format!("{ev};"))).await?;
@ -2400,13 +2431,11 @@ impl Transaction {
&mut self,
ns: &str,
db: &str,
tb: &DefineTableStatement,
tb: &str,
id: &Thing,
v: Cow<'_, Value>,
) {
if tb.changefeed.is_some() {
self.cf.update(ns, db, tb.name.to_owned(), id.clone(), v)
}
self.cf.update(ns, db, tb, id.clone(), v)
}
pub(crate) async fn get_idg(&mut self, key: Key) -> Result<U32, Error> {

View file

@ -178,11 +178,11 @@ impl Function {
// Claim transaction
let mut run = txn.lock().await;
// Get the function definition
run.get_fc(opt.ns(), opt.db(), s).await?
run.get_and_cache_db_function(opt.ns(), opt.db(), s).await?
};
// Check permissions
if opt.check_perms(Action::View) {
match val.permissions {
match &val.permissions {
Permission::Full => (),
Permission::None => {
return Err(Error::FunctionPermissions {
@ -217,8 +217,8 @@ impl Function {
// Duplicate context
let mut ctx = Context::new(ctx);
// Process the function arguments
for (val, (name, kind)) in a.into_iter().zip(val.args) {
ctx.add_value(name.to_raw(), val.coerce_to(&kind)?);
for (val, (name, kind)) in a.into_iter().zip(&val.args) {
ctx.add_value(name.to_raw(), val.coerce_to(kind)?);
}
// Run the custom function
val.block.compute(&ctx, opt, txn, doc).await

View file

@ -110,19 +110,19 @@ impl Idiom {
.collect::<Vec<_>>()
.into()
}
/// Check if this expression is an 'id' field
/// Check if this Idiom is an 'id' field
pub(crate) fn is_id(&self) -> bool {
self.0.len() == 1 && self.0[0].eq(&ID[0])
}
/// Check if this expression is an 'in' field
/// Check if this Idiom is an 'in' field
pub(crate) fn is_in(&self) -> bool {
self.0.len() == 1 && self.0[0].eq(&IN[0])
}
/// Check if this expression is an 'out' field
/// Check if this Idiom is an 'out' field
pub(crate) fn is_out(&self) -> bool {
self.0.len() == 1 && self.0[0].eq(&OUT[0])
}
/// Check if this expression is an 'out' field
/// Check if this Idiom is a 'meta' field
pub(crate) fn is_meta(&self) -> bool {
self.0.len() == 1 && self.0[0].eq(&META[0])
}

View file

@ -208,7 +208,7 @@ impl Number {
match self {
Number::Int(_) => true,
Number::Float(v) => v.fract() == 0.0,
Number::Decimal(v) => decimal_is_integer(v),
Number::Decimal(v) => v.is_integer(),
}
}
@ -686,29 +686,12 @@ pub fn integer(i: &str) -> IResult<&str, i64> {
Ok((i, v))
}
/// TODO: This slow but temporary (awaiting https://docs.rs/rust_decimal/latest/rust_decimal/ version >1.29.1)
pub(crate) fn decimal_is_integer(decimal: &Decimal) -> bool {
decimal.fract().is_zero()
}
#[cfg(test)]
mod tests {
use super::*;
use std::ops::Div;
#[test]
fn dec_is_integer() {
assert!(decimal_is_integer(&Decimal::MAX));
assert!(decimal_is_integer(&Decimal::MIN));
for n in -10..10 {
assert!(decimal_is_integer(&Decimal::from(n)));
assert!(!decimal_is_integer(&(Decimal::from(n) + Decimal::from_f32(0.1).unwrap())));
}
assert!(!decimal_is_integer(&Decimal::HALF_PI));
}
#[test]
fn number_nan() {
let sql = "NaN";

View file

@ -75,7 +75,7 @@ impl Param {
// Claim transaction
let mut run = txn.lock().await;
// Get the param definition
run.get_pa(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 {
@ -83,7 +83,7 @@ impl Param {
Ok(val) => {
// Check permissions
if opt.check_perms(Action::View) {
match val.permissions {
match &val.permissions {
Permission::Full => (),
Permission::None => {
return Err(Error::ParamPermissions {
@ -103,7 +103,7 @@ impl Param {
}
}
// Return the value
Ok(val.value)
Ok(val.value.to_owned())
}
// The param has not been set globally
Err(_) => Ok(Value::None),

View file

@ -43,13 +43,15 @@ impl AnalyzeStatement {
// Claim transaction
let mut run = txn.lock().await;
// Read the index
let ix = run.get_ix(opt.ns(), opt.db(), tb.as_str(), idx.as_str()).await?;
let ix = run
.get_and_cache_tb_index(opt.ns(), opt.db(), tb.as_str(), idx.as_str())
.await?;
let ikb = IndexKeyBase::new(opt, &ix);
// Index operation dispatching
let value: Value = match &ix.index {
Index::Search(p) => {
let az = run.get_az(opt.ns(), opt.db(), p.az.as_str()).await?;
let az = run.get_db_analyzer(opt.ns(), opt.db(), p.az.as_str()).await?;
let ft =
FtIndex::new(&mut run, az, ikb, p, TreeStoreType::Traversal).await?;
ft.statistics(&mut run).await?.into()

View file

@ -86,7 +86,7 @@ impl InfoStatement {
res.insert("users".to_owned(), tmp.into());
// Process the tokens
let mut tmp = Object::default();
for v in run.all_nt(opt.ns()).await?.iter() {
for v in run.all_ns_tokens(opt.ns()).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("tokens".to_owned(), tmp.into());
@ -108,19 +108,19 @@ impl InfoStatement {
res.insert("users".to_owned(), tmp.into());
// Process the tokens
let mut tmp = Object::default();
for v in run.all_dt(opt.ns(), opt.db()).await?.iter() {
for v in run.all_db_tokens(opt.ns(), opt.db()).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("tokens".to_owned(), tmp.into());
// Process the functions
let mut tmp = Object::default();
for v in run.all_fc(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 params
let mut tmp = Object::default();
for v in run.all_pa(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());
@ -138,7 +138,7 @@ impl InfoStatement {
res.insert("tables".to_owned(), tmp.into());
// Process the analyzers
let mut tmp = Object::default();
for v in run.all_az(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());
@ -154,7 +154,7 @@ impl InfoStatement {
let mut res = Object::default();
// Process the tokens
let mut tmp = Object::default();
for v in run.all_st(opt.ns(), opt.db(), sc).await?.iter() {
for v in run.all_sc_tokens(opt.ns(), opt.db(), sc).await?.iter() {
tmp.insert(v.name.to_string(), v.to_string().into());
}
res.insert("tokens".to_owned(), tmp.into());
@ -170,25 +170,25 @@ impl InfoStatement {
let mut res = Object::default();
// Process the events
let mut tmp = Object::default();
for v in run.all_ev(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_fd(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_ft(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_ix(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());

View file

@ -110,7 +110,7 @@ impl InsertStatement {
_ => unreachable!(),
},
v => {
return Err(Error::RelateStatement {
return Err(Error::InsertStatement {
value: v.to_string(),
})
}

View file

@ -139,8 +139,7 @@ pub fn live(i: &str) -> IResult<&str, LiveStatement> {
what,
cond,
fetch,
archived: None,
auth: None, // Auth is set via options in compute()
..Default::default()
},
))
})(i)

View file

@ -71,7 +71,7 @@ impl Value {
},
Part::Index(i) => match path.len() {
1 => {
if v.len().gt(&i.to_usize()) {
if v.len() > i.to_usize() {
v.remove(i.to_usize());
}
}

View file

@ -102,7 +102,7 @@ impl Value {
},
Part::Index(i) => match path.len() {
1 => {
if v.len().gt(&i.to_usize()) {
if v.len() > i.to_usize() {
v.remove(i.to_usize());
}
Ok(())
@ -168,7 +168,7 @@ impl Value {
Part::Value(x) => match x.compute(ctx, opt, txn, None).await? {
Value::Number(i) => match path.len() {
1 => {
if v.len().gt(&i.to_usize()) {
if v.len() > i.to_usize() {
v.remove(i.to_usize());
}
Ok(())

View file

@ -27,7 +27,6 @@ use crate::sql::id::{Gen, Id};
use crate::sql::idiom::{self, reparse_idiom_start, Idiom};
use crate::sql::kind::Kind;
use crate::sql::model::{model, Model};
use crate::sql::number::decimal_is_integer;
use crate::sql::number::{number, Number};
use crate::sql::object::{key, object, Object};
use crate::sql::operation::Operation;
@ -815,7 +814,7 @@ impl Value {
/// Check if this Value is a boolean value
pub fn is_bool(&self) -> bool {
self.is_true() || self.is_false()
matches!(self, Value::Bool(_))
}
/// Check if this Value is TRUE or 'true'
@ -1098,7 +1097,7 @@ impl Value {
}
// -----------------------------------
// Simple conversion of value
// Simple conversion of values
// -----------------------------------
/// Treat a string as a table name
@ -1225,7 +1224,7 @@ impl Value {
// Attempt to convert an float number
Value::Number(Number::Float(v)) if v.fract() == 0.0 => Ok(v as i64),
// Attempt to convert a decimal number
Value::Number(Number::Decimal(v)) if decimal_is_integer(&v) => match v.try_into() {
Value::Number(Number::Decimal(v)) if v.is_integer() => match v.try_into() {
// The Decimal can be represented as an i64
Ok(v) => Ok(v),
// The Decimal is out of bounds
@ -1250,7 +1249,7 @@ impl Value {
// Attempt to convert an float number
Value::Number(Number::Float(v)) if v.fract() == 0.0 => Ok(v as u64),
// Attempt to convert a decimal number
Value::Number(Number::Decimal(v)) if decimal_is_integer(&v) => match v.try_into() {
Value::Number(Number::Decimal(v)) if v.is_integer() => match v.try_into() {
// The Decimal can be represented as an u64
Ok(v) => Ok(v),
// The Decimal is out of bounds
@ -1326,7 +1325,7 @@ impl Value {
// Attempt to convert an float number
Value::Number(Number::Float(v)) if v.fract() == 0.0 => Ok(Number::Int(v as i64)),
// Attempt to convert a decimal number
Value::Number(Number::Decimal(ref v)) if decimal_is_integer(v) => match v.to_i64() {
Value::Number(Number::Decimal(v)) if v.is_integer() => match v.to_i64() {
// The Decimal can be represented as an Int
Some(v) => Ok(Number::Int(v)),
// The Decimal is out of bounds
@ -1800,7 +1799,7 @@ impl Value {
// Attempt to convert an float number
Value::Number(Number::Float(v)) if v.fract() == 0.0 => Ok(Number::Int(v as i64)),
// Attempt to convert a decimal number
Value::Number(Number::Decimal(v)) if decimal_is_integer(&v) => match v.try_into() {
Value::Number(Number::Decimal(v)) if v.is_integer() => match v.try_into() {
// The Decimal can be represented as an Int
Ok(v) => Ok(Number::Int(v)),
// The Decimal is out of bounds