Code cleanup (#2569)
This commit is contained in:
parent
ed48fddd2a
commit
e9ee5245c2
29 changed files with 385 additions and 376 deletions
|
@ -1,4 +1,4 @@
|
|||
<h1><img height="25" src="./img/contributing.svg"> Contributing</h1>
|
||||
# Contributing
|
||||
|
||||
We would <img width="15" src="./img/love.svg"> 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)
|
||||
|
|
|
@ -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 don’t currently have ORM support in the drivers themselves, and aren’t 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 don’t currently have ORM support in the drivers themselves, and aren’t 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?
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?;
|
||||
|
|
|
@ -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())),
|
||||
},
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -110,7 +110,7 @@ impl InsertStatement {
|
|||
_ => unreachable!(),
|
||||
},
|
||||
v => {
|
||||
return Err(Error::RelateStatement {
|
||||
return Err(Error::InsertStatement {
|
||||
value: v.to_string(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue