Change meta functions to record and add record::exists() function (#4602)

This commit is contained in:
Tobie Morgan Hitchcock 2024-08-25 10:01:43 +01:00 committed by GitHub
parent 7adbe3cd34
commit 419f5d52c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 129 additions and 76 deletions

View file

@ -1,11 +0,0 @@
use crate::err::Error;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
pub fn id((arg,): (Thing,)) -> Result<Value, Error> {
Ok(arg.id.into())
}
pub fn tb((arg,): (Thing,)) -> Result<Value, Error> {
Ok(arg.tb.into())
}

View file

@ -18,12 +18,12 @@ pub mod encoding;
pub mod geo;
pub mod http;
pub mod math;
pub mod meta;
pub mod not;
pub mod object;
pub mod operate;
pub mod parse;
pub mod rand;
pub mod record;
pub mod script;
pub mod search;
pub mod session;
@ -54,6 +54,7 @@ pub async fn run(
|| name.starts_with("crypto::pbkdf2")
|| name.starts_with("crypto::scrypt")
|| name.starts_with("array::map")
|| name.starts_with("record::exists")
{
stk.run(|stk| asynchronous(stk, ctx, opt, doc, name, args)).await
} else {
@ -228,10 +229,6 @@ pub fn synchronous(
"math::trimean" => math::trimean,
"math::variance" => math::variance,
//
"meta::id" => meta::id,
"meta::table" => meta::tb,
"meta::tb" => meta::tb,
//
"not" => not::not,
//
"object::entries" => object::entries,
@ -263,6 +260,10 @@ pub fn synchronous(
"rand::uuid::v7" => rand::uuid::v7,
"rand::uuid" => rand::uuid,
//
"record::id" => record::id,
"record::table" => record::tb,
"record::tb" => record::tb,
//
"session::ac" => session::ac(ctx),
"session::db" => session::db(ctx),
"session::id" => session::id(ctx),
@ -550,9 +551,10 @@ pub async fn idiom(
name,
args.clone(),
"no such method found for the record type",
"id" => meta::id,
"table" => meta::tb,
"tb" => meta::tb,
"exists" => record::exists((stk, ctx, Some(opt), doc)).await,
"id" => record::id,
"table" => record::tb,
"tb" => record::tb,
)
}
Value::Object(_) => {
@ -760,15 +762,17 @@ pub async fn asynchronous(
"http::patch" => http::patch(ctx).await,
"http::delete" => http::delete(ctx).await,
//
"search::analyze" => search::analyze((stk,ctx, Some(opt))).await,
"record::exists" => record::exists((stk, ctx, Some(opt), doc)).await,
//
"search::analyze" => search::analyze((stk, ctx, Some(opt))).await,
"search::score" => search::score((ctx, doc)).await,
"search::highlight" => search::highlight((ctx, doc)).await,
"search::offsets" => search::offsets((ctx, doc)).await,
//
"sleep" => sleep::sleep(ctx).await,
//
"type::field" => r#type::field((stk,ctx, Some(opt), doc)).await,
"type::fields" => r#type::fields((stk,ctx, Some(opt), doc)).await,
"type::field" => r#type::field((stk, ctx, Some(opt), doc)).await,
"type::fields" => r#type::fields((stk, ctx, Some(opt), doc)).await,
)
}

30
core/src/fnc/record.rs Normal file
View file

@ -0,0 +1,30 @@
use crate::ctx::Context;
use crate::dbs::Options;
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::sql::paths::ID;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use reblessive::tree::Stk;
pub async fn exists(
(stk, ctx, opt, doc): (&mut Stk, &Context, Option<&Options>, Option<&CursorDoc>),
(arg,): (Thing,),
) -> Result<Value, Error> {
if let Some(opt) = opt {
Ok(match Value::Thing(arg).get(stk, ctx, opt, doc, ID.as_ref()).await? {
Value::None => Value::Bool(false),
_ => Value::Bool(true),
})
} else {
Ok(Value::None)
}
}
pub fn id((arg,): (Thing,)) -> Result<Value, Error> {
Ok(arg.id.into())
}
pub fn tb((arg,): (Thing,)) -> Result<Value, Error> {
Ok(arg.tb.into())
}

View file

@ -16,10 +16,10 @@ mod encoding;
mod geo;
mod http;
mod math;
mod meta;
mod object;
mod parse;
mod rand;
mod record;
mod search;
mod session;
mod string;
@ -42,12 +42,11 @@ impl_module_def!(
"geo" => (geo::Package),
"http" => (http::Package),
"math" => (math::Package),
"meta" => (meta::Package),
"object" => (object::Package),
"not" => run,
"object" => (object::Package),
"parse" => (parse::Package),
"rand" => (rand::Package),
"array" => (array::Package),
"record" => (record::Package),
"search" => (search::Package),
"session" => (session::Package),
"sleep" => fut Async,

View file

@ -1,12 +1,15 @@
use super::fut;
use super::run;
use crate::fnc::script::modules::impl_module_def;
use js::prelude::Async;
#[non_exhaustive]
pub struct Package;
impl_module_def!(
Package,
"meta",
"record",
"exists" => fut Async,
"id" => run,
"table" => run,
"tb" => run

View file

@ -1636,7 +1636,7 @@ dn/RsYEONbwQSjIfMPkvxF+8HQ==
)
AUTHENTICATE (
-- Simple example increasing the record identifier by one
SELECT * FROM type::thing('user', meta::id($auth) + 1)
SELECT * FROM type::thing('user', record::id($auth) + 1)
)
DURATION FOR SESSION 2h
;
@ -1716,7 +1716,7 @@ dn/RsYEONbwQSjIfMPkvxF+8HQ==
)
AUTHENTICATE (
-- If logging in with a company account, the session will be authenticated as the first owner
IF meta::tb($auth) = "company" {
IF record::tb($auth) = "company" {
RETURN SELECT VALUE owner FROM company WHERE id = $auth
}
)

View file

@ -457,7 +457,7 @@ dn/RsYEONbwQSjIfMPkvxF+8HQ==
)
AUTHENTICATE (
-- Simple example increasing the record identifier by one
SELECT * FROM type::thing('user', meta::id($auth) + 1)
SELECT * FROM type::thing('user', record::id($auth) + 1)
)
DURATION FOR SESSION 2h
;
@ -537,7 +537,7 @@ dn/RsYEONbwQSjIfMPkvxF+8HQ==
)
AUTHENTICATE (
-- If logging in with a company account, the session will be authenticated as the first owner
IF meta::tb($auth) = "company" {
IF record::tb($auth) = "company" {
RETURN SELECT VALUE owner FROM company WHERE id = $auth
}
)

View file

@ -1997,7 +1997,7 @@ mod tests {
WITH JWT ALGORITHM HS512 KEY '{secret}'
AUTHENTICATE (
-- Simple example increasing the record identifier by one
SELECT * FROM type::thing('user', meta::id($auth) + 1)
SELECT * FROM type::thing('user', record::id($auth) + 1)
)
DURATION FOR SESSION 2h
;

View file

@ -221,10 +221,6 @@ pub(crate) static PATHS: phf::Map<UniCase<&'static str>, PathKind> = phf_map! {
UniCase::ascii("math::trimean") => PathKind::Function,
UniCase::ascii("math::variance") => PathKind::Function,
//
UniCase::ascii("meta::id") => PathKind::Function,
UniCase::ascii("meta::table") => PathKind::Function,
UniCase::ascii("meta::tb") => PathKind::Function,
//
UniCase::ascii("not") => PathKind::Function,
//
UniCase::ascii("parse::email::host") => PathKind::Function,
@ -250,6 +246,11 @@ pub(crate) static PATHS: phf::Map<UniCase<&'static str>, PathKind> = phf_map! {
UniCase::ascii("rand::uuid::v7") => PathKind::Function,
UniCase::ascii("rand::uuid") => PathKind::Function,
//
UniCase::ascii("record::exists") => PathKind::Function,
UniCase::ascii("record::id") => PathKind::Function,
UniCase::ascii("record::table") => PathKind::Function,
UniCase::ascii("record::tb") => PathKind::Function,
//
UniCase::ascii("session::db") => PathKind::Function,
UniCase::ascii("session::id") => PathKind::Function,
UniCase::ascii("session::ip") => PathKind::Function,

View file

@ -247,10 +247,6 @@
"math::round("
"math::sqrt("
"math::sum("
"meta"
"meta::"
"meta::id("
"meta::tb("
"object::entries("
"object::from_entries("
"object::keys("
@ -278,6 +274,12 @@
"rand::string("
"rand::time("
"rand::uuid("
"record"
"record::"
"record::exists("
"record::id("
"record::table("
"record::tb("
"uuid"
"rand::uuid::v4("
"rand::uuid::v7("

View file

@ -246,10 +246,6 @@
"math::round("
"math::sqrt("
"math::sum("
"meta"
"meta::"
"meta::id("
"meta::tb("
"object::entries("
"object::from_entries("
"object::keys("
@ -277,6 +273,12 @@
"rand::string("
"rand::time("
"rand::uuid("
"record"
"record::"
"record::exists("
"record::id("
"record::table("
"record::tb("
"uuid"
"rand::uuid::v4("
"rand::uuid::v7("

View file

@ -2666,38 +2666,6 @@ async fn function_math_variance() -> Result<(), Error> {
Ok(())
}
// --------------------------------------------------
// meta
// --------------------------------------------------
#[tokio::test]
async fn function_parse_meta_id() -> Result<(), Error> {
let sql = r#"
RETURN meta::id(r"person:tobie");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::from("tobie");
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_meta_table() -> Result<(), Error> {
let sql = r#"
RETURN meta::table(r"person:tobie");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::from("person");
assert_eq!(tmp, val);
//
Ok(())
}
// --------------------------------------------------
// object
// --------------------------------------------------
@ -3237,6 +3205,61 @@ async fn function_rand_uuid_v7_from_datetime() -> Result<(), Error> {
Ok(())
}
// --------------------------------------------------
// record
// --------------------------------------------------
#[tokio::test]
async fn function_parse_record_exists() -> Result<(), Error> {
let sql = r#"
RETURN record::exists(r"person:tobie");
CREATE ONLY person:tobie;
RETURN record::exists(r"person:tobie");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::from(false);
assert_eq!(tmp, val);
//
let tmp = test.next()?.result?;
assert!(tmp.is_object());
//
let tmp = test.next()?.result?;
let val = Value::from(true);
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_record_id() -> Result<(), Error> {
let sql = r#"
RETURN record::id(r"person:tobie");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::from("tobie");
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_record_table() -> Result<(), Error> {
let sql = r#"
RETURN record::table(r"person:tobie");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::from("person");
assert_eq!(tmp, val);
//
Ok(())
}
// --------------------------------------------------
// string
// --------------------------------------------------