time functions for WASM

main
Ziyang Hu 2 years ago
parent 54623cb4d0
commit 5d41f028ea

1
Cargo.lock generated

@ -494,6 +494,7 @@ dependencies = [
"either",
"env_logger",
"itertools 0.10.5",
"js-sys",
"lazy_static",
"log",
"miette",

@ -1,5 +1,5 @@
[profile.release]
lto = true
#[profile.release]
#lto = true
[workspace]
members = ["cozorocks", "cozo-lib-c", "cozo-lib-java", "cozo-core", "cozoserver", "cozo-lib-wasm"]

@ -38,7 +38,7 @@ jemalloc = ["dep:tikv-jemallocator-global", "cozorocks?/jemalloc"]
## Enables io-uring option for the RocksDB storage
io-uring = ["cozorocks?/io-uring"]
## Enables the WASM target
wasm = ["uuid/js"]
wasm = ["uuid/js", "dep:js-sys"]
## Allows threading and enables the use of the `rayon` library for parallelizing algorithms
rayon = ["dep:rayon"]
## Disallows the use of threads
@ -94,5 +94,6 @@ sled = { version = "0.34.7", optional = true }
tikv-client = { version = "0.1.0", optional = true }
tokio = { version = "1.21.2", optional = true }
sqlite = { version = "0.30.1", optional = true }
js-sys = { version = "0.3.60", optional = true }
#redb = "0.9.0"
#ouroboros = "0.15.5"

@ -13,6 +13,8 @@ use std::time::{SystemTime, UNIX_EPOCH};
use chrono::{DateTime, TimeZone, Utc};
use itertools::Itertools;
#[cfg(feature = "wasm")]
use js_sys::Date;
use miette::{bail, ensure, miette, Result};
use num_traits::FloatConst;
use rand::prelude::*;
@ -1434,7 +1436,8 @@ pub(crate) fn op_to_uuid(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_NOW, 0, false);
#[cfg(feature = "wasm")]
pub(crate) fn op_now(_args: &[DataValue]) -> Result<DataValue> {
bail!("`op_now` is not supported under WASM runtime")
let d: f64 = Date::now() / 1000.;
Ok(DataValue::from(d))
}
#[cfg(not(feature = "wasm"))]
pub(crate) fn op_now(_args: &[DataValue]) -> Result<DataValue> {
@ -1445,20 +1448,22 @@ pub(crate) fn op_now(_args: &[DataValue]) -> Result<DataValue> {
}
define_op!(OP_FORMAT_TIMESTAMP, 1, true);
pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
#[cfg(feature = "wasm")]
pub(crate) fn op_format_timestamp(_args: &[DataValue]) -> Result<DataValue> {
bail!("`format_timestamp` is not supported under WASM")
}
let dt = Utc
.timestamp_millis_opt(Date::now() as i64)
.latest()
.ok_or_else(|| miette!("bad time input"))?;
#[cfg(not(feature = "wasm"))]
pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
let dt = {
let f = args[0]
.get_float()
.ok_or_else(|| miette!("'format_timestamp' expects a number"))?;
let millis = (f * 1000.) as i64;
let dt = Utc
.timestamp_millis_opt(millis)
Utc.timestamp_millis_opt(millis)
.latest()
.ok_or_else(|| miette!("bad time: {}", f))?;
.ok_or_else(|| miette!("bad time: {}", f))?
};
match args.get(1) {
Some(tz_v) => {
let tz_s = tz_v.get_string().ok_or_else(|| {
@ -1478,11 +1483,6 @@ pub(crate) fn op_format_timestamp(args: &[DataValue]) -> Result<DataValue> {
}
define_op!(OP_PARSE_TIMESTAMP, 1, false);
#[cfg(feature = "wasm")]
pub(crate) fn op_parse_timestamp(_args: &[DataValue]) -> Result<DataValue> {
bail!("`parse_timestamp` is not supported under WASM")
}
#[cfg(not(feature = "wasm"))]
pub(crate) fn op_parse_timestamp(args: &[DataValue]) -> Result<DataValue> {
let s = args[0]
.get_string()
@ -1495,17 +1495,22 @@ pub(crate) fn op_parse_timestamp(args: &[DataValue]) -> Result<DataValue> {
}
define_op!(OP_RAND_UUID_V1, 0, false);
#[cfg(feature = "wasm")]
pub(crate) fn op_rand_uuid_v1(_args: &[DataValue]) -> Result<DataValue> {
bail!("`rand_uuid_v1` is not supported under WASM")
}
#[cfg(not(feature = "wasm"))]
pub(crate) fn op_rand_uuid_v1(_args: &[DataValue]) -> Result<DataValue> {
let mut rng = rand::thread_rng();
let uuid_ctx = uuid::v1::Context::new(rng.gen());
#[cfg(feature = "wasm")]
let ts = {
let since_epoch: f64 = Date::now();
let seconds = since_epoch.floor();
let fractional = (since_epoch - seconds) * 1.0e9;
Timestamp::from_unix(uuid_ctx, seconds as u64, fractional as u32)
};
#[cfg(not(feature = "wasm"))]
let ts = {
let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH).unwrap();
let ts = Timestamp::from_unix(uuid_ctx, since_epoch.as_secs(), since_epoch.subsec_nanos());
Timestamp::from_unix(uuid_ctx, since_epoch.as_secs(), since_epoch.subsec_nanos())
};
let mut rand_vals = [0u8; 6];
rng.fill(&mut rand_vals);
let id = uuid::Uuid::new_v1(ts, &rand_vals);

@ -8,8 +8,8 @@
use std::collections::BTreeMap;
use std::fmt::{Debug, Formatter};
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
@ -17,7 +17,7 @@ use either::{Left, Right};
use itertools::Itertools;
use lazy_static::lazy_static;
use miette::{
bail, Diagnostic, ensure, GraphicalReportHandler, GraphicalTheme, IntoDiagnostic,
bail, ensure, Diagnostic, GraphicalReportHandler, GraphicalTheme, IntoDiagnostic,
JSONReportHandler, Result, WrapErr,
};
use serde_json::{json, Map};
@ -28,8 +28,8 @@ use crate::data::json::JsonValue;
use crate::data::program::{InputProgram, QueryAssertion, RelationOp};
use crate::data::tuple::Tuple;
use crate::data::value::{DataValue, LARGEST_UTF_CHAR};
use crate::parse::{CozoScript, parse_script, SourceSpan};
use crate::parse::sys::SysOp;
use crate::parse::{parse_script, CozoScript, SourceSpan};
use crate::query::compile::{CompiledProgram, CompiledRule, CompiledRuleSet};
use crate::query::relation::{
FilteredRA, InMemRelationRA, InnerJoin, NegJoin, RelAlgebra, ReorderRA, StoredRA, UnificationRA,
@ -573,7 +573,7 @@ impl<'s, S: Storage<'s>> Db<S> {
.as_secs_f64();
#[cfg(feature = "wasm")]
let since_the_epoch = 0.;
let since_the_epoch = js_sys::Date::now();
let handle = RunningQueryHandle {
started_at: since_the_epoch,

@ -61,6 +61,10 @@ query(`
?[loved_by_e_not_b] := *love['eve', loved_by_e_not_b], not *love['bob', loved_by_e_not_b]
`);
query(`
?[] <- [[parse_timestamp(format_timestamp(now(), 'Asia/Shanghai')),]]
`);
query(`
?[] <- [[rand_uuid_v1()]]
`);
Loading…
Cancel
Save