Add versioned data storage serialisation (#2433)

This commit is contained in:
Tobie Morgan Hitchcock 2023-08-17 19:03:46 +01:00 committed by GitHub
parent 983ec1ba63
commit b2b51b54b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
105 changed files with 950 additions and 364 deletions

446
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -34,13 +34,13 @@ strip = false
[dependencies]
argon2 = "0.5.1"
axum = { version = "0.6.19", features = ["tracing", "ws", "headers"] }
axum = { version = "0.6.20", features = ["tracing", "ws", "headers"] }
axum-client-ip = "0.4.1"
axum-extra = { version = "0.7.5", features = ["typed-routing"] }
axum-extra = { version = "0.7.7", features = ["typed-routing"] }
axum-server = { version = "0.5.1", features = ["tls-rustls"] }
base64 = "0.21.2"
bytes = "1.4.0"
clap = { version = "4.3.16", features = ["env", "derive", "wrap_help", "unicode"] }
clap = { version = "4.3.21", features = ["env", "derive", "wrap_help", "unicode"] }
futures = "0.3.28"
futures-util = "0.3.28"
glob = "0.3.1"
@ -51,26 +51,26 @@ ipnet = "2.8.0"
once_cell = "1.18.0"
opentelemetry = { version = "0.19", features = ["rt-tokio"] }
opentelemetry-otlp = { version = "0.12.0", features = ["metrics"] }
pin-project-lite = "0.2.10"
pin-project-lite = "0.2.12"
rand = "0.8.5"
reqwest = { version = "0.11.18", default-features = false, features = ["blocking"] }
rustyline = { version = "11.0.0", features = ["derive"] }
serde = { version = "1.0.171", features = ["derive"] }
serde = { version = "1.0.183", features = ["derive"] }
serde_cbor = "0.11.2"
serde_json = "1.0.103"
serde_pack = { version = "1.1.1", package = "rmp-serde" }
serde_json = "1.0.104"
serde_pack = { version = "1.1.2", package = "rmp-serde" }
surrealdb = { path = "lib", features = ["protocol-http", "protocol-ws", "rustls"] }
tempfile = "3.6.0"
thiserror = "1.0.43"
tokio = { version = "1.29.1", features = ["macros", "signal"] }
tempfile = "3.7.1"
thiserror = "1.0.44"
tokio = { version = "1.31.0", features = ["macros", "signal"] }
tokio-util = { version = "0.7.8", features = ["io"] }
tower = "0.4.13"
tower-http = { version = "0.4.2", features = ["trace", "sensitive-headers", "auth", "request-id", "util", "catch-panic", "cors", "set-header", "limit", "add-extension"] }
tower-http = { version = "0.4.3", features = ["trace", "sensitive-headers", "auth", "request-id", "util", "catch-panic", "cors", "set-header", "limit", "add-extension"] }
tracing = "0.1"
tracing-futures = { version = "0.2.5", features = ["tokio"], default-features = false }
tracing-opentelemetry = "0.19.0"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
urlencoding = "2.1.2"
urlencoding = "2.1.3"
uuid = { version = "1.4.1", features = ["serde", "js", "v4", "v7"] }
[target.'cfg(unix)'.dependencies]

View file

@ -58,24 +58,25 @@ async-recursion = "1.0.4"
base64_lib = { version = "0.21.2", package = "base64" }
bcrypt = "0.14.0"
bincode = "1.3.3"
bung = "0.1.0"
bytes = "1.4.0"
cedar-policy = "2.3.2"
channel = { version = "1.9.0", package = "async-channel" }
chrono = { version = "0.4.26", features = ["serde"] }
derive = { version = "0.9.0", package = "surrealdb-derive" }
derive = { version = "0.12.0", package = "surrealdb-derive" }
deunicode = "1.3.3"
dmp = "0.2.0"
echodb = { version = "0.4.0", optional = true }
executor = { version = "1.5.1", package = "async-executor" }
flume = "0.10.14"
fst = "0.4.7"
foundationdb = { version = "0.8.0", default-features = false, features = ["embedded-fdb-include"], optional = true }
fst = "0.4.7"
futures = "0.3.28"
futures-concurrency = "7.3.0"
fuzzy-matcher = "0.3.7"
geo = { version = "0.25.1", features = ["use-serde"] }
indexmap = { version = "1.9.3", features = ["serde"] }
indxdb = { version = "0.3.0", optional = true }
js = { version = "0.4.0-beta.3" , package = "rquickjs", features = ["array-buffer", "bindgen", "classes", "futures", "loader", "macro", "parallel", "properties","rust-alloc"], optional = true }
js = { version = "0.4.0-beta.3", package = "rquickjs", features = ["array-buffer", "bindgen", "classes", "futures", "loader", "macro", "parallel", "properties","rust-alloc"], optional = true }
jsonwebtoken = "8.3.0"
lexicmp = "0.1.0"
lru = "0.10.1"
@ -85,57 +86,56 @@ native-tls = { version = "0.2.11", optional = true }
nom = { version = "7.1.3", features = ["alloc"] }
once_cell = "1.18.0"
pbkdf2 = { version = "0.12.2", features = ["simple"] }
pin-project-lite = "0.2.10"
pin-project-lite = "0.2.12"
radix_trie = { version = "0.2.1", features = ["serde"] }
rand = "0.8.5"
regex = "1.9.1"
reqwest = { version = "0.11.18", default-features = false, features = ["json", "stream","multipart"], optional = true }
roaring = { version = "0.10.1", features = ["serde"] }
regex = "1.9.3"
reqwest = { version = "0.11.18", default-features = false, features = ["json", "stream", "multipart"], optional = true }
revision = "0.4.0"
roaring = { version = "0.10.2", features = ["serde"] }
rocksdb = { version = "0.21.0", optional = true }
rust_decimal = { version = "1.30.0", features = [ "maths" ] }
rust_decimal = { version = "1.31.0", features = ["maths"] }
rust-stemmers = "1.2.0"
rustls = { version = "0.20.8", optional = true }
snap = "1.1.0"
scrypt = "0.11.0"
semver = { version = "1.0.18", features = ["serde"] }
serde = { version = "1.0.171", features = ["derive"] }
serde_json = "1.0.103"
serde = { version = "1.0.183", features = ["derive"] }
serde_json = "1.0.104"
sha-1 = "0.10.1"
sha2 = "0.10.7"
snap = "1.1.0"
speedb = { version = "0.0.2", optional = true }
storekey = "0.5.0"
thiserror = "1.0.43"
thiserror = "1.0.44"
tikv = { version = "0.2.0-surreal.2", default-features = false, package = "surrealdb-tikv-client", optional = true }
tokio-util = { version = "0.7.8", optional = true, features = ["compat"] }
tracing = "0.1.37"
trice = "0.3.1"
ulid = { version = "1.0.0", features = ["serde"] }
url = "2.4.0"
bytes = "1.4.0"
cedar-policy = "2.2.0"
[dev-dependencies]
criterion = { version="0.4", features= [ "async_futures" ] }
criterion = { version="0.4", features= ["async_futures"] }
env_logger = "0.10.0"
test-log = "0.2.12"
pprof = { version = "0.11.1", features = [ "flamegraph", "criterion" ] }
pprof = { version = "0.11.1", features = ["flamegraph", "criterion"] }
serial_test = "2.0.0"
temp-dir = "0.1.11"
time = { version = "0.3.23", features = ["serde"] }
tokio = { version = "1.29.1", features = ["macros", "sync", "rt-multi-thread"] }
test-log = "0.2.12"
time = { version = "0.3.25", features = ["serde"] }
tokio = { version = "1.31.0", features = ["macros", "sync", "rt-multi-thread"] }
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
wiremock = "0.5.19"
[target.'cfg(target_arch = "wasm32")'.dependencies]
pharos = "0.5.3"
tokio = { version = "1.29.1", default-features = false, features = ["rt", "sync"] }
tokio = { version = "1.31.0", default-features = false, features = ["rt", "sync"] }
uuid = { version = "1.4.1", features = ["serde", "js", "v4", "v7"] }
wasmtimer = { version = "0.2.0", default-features = false, features = ["tokio"] }
wasm-bindgen-futures = "0.4.37"
wasmtimer = { version = "0.2.0", default-features = false, features = ["tokio"] }
ws_stream_wasm = "0.7.4"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1.29.1", default-features = false, features = ["macros", "io-util", "io-std", "fs", "rt-multi-thread", "time", "sync"] }
tokio = { version = "1.31.0", default-features = false, features = ["macros", "io-util", "io-std", "fs", "rt-multi-thread", "time", "sync"] }
tokio-tungstenite = { version = "0.18.0", optional = true }
uuid = { version = "1.4.1", features = ["serde", "v4", "v7"] }

View file

@ -7,6 +7,6 @@ publish = false
[dependencies]
actix-web = { version = "4.3.1", features = ["macros"] }
once_cell = "1.18.0"
serde = { version = "1.0.171", features = ["derive"] }
serde = { version = "1.0.183", features = ["derive"] }
surrealdb = { path = "../.." }
thiserror = "1.0.43"
thiserror = "1.0.44"

View file

@ -5,8 +5,8 @@ edition = "2021"
publish = false
[dependencies]
axum = "0.6.19"
serde = { version = "1.0.171", features = ["derive"] }
axum = "0.6.20"
serde = { version = "1.0.183", features = ["derive"] }
surrealdb = { path = "../.." }
thiserror = "1.0.43"
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
thiserror = "1.0.44"
tokio = { version = "1.31.0", features = ["macros", "rt-multi-thread"] }

View file

@ -17,7 +17,7 @@ use crate::api::OnceLockExt;
use crate::api::Result;
use crate::api::Surreal;
use crate::engine::remote::ws::IntervalStream;
use crate::sql::serde::deserialize;
use crate::sql::serde::{deserialize, serialize};
use crate::sql::Strand;
use crate::sql::Value;
use flume::Receiver;
@ -172,7 +172,8 @@ pub(crate) fn router(
let mut request = BTreeMap::new();
request.insert("method".to_owned(), PING_METHOD.into());
let value = Value::from(request);
Message::Binary(value.into())
let value = serialize(&value).unwrap();
Message::Binary(value)
};
let mut vars = IndexMap::new();
@ -244,7 +245,8 @@ pub(crate) fn router(
}
let payload = Value::from(request);
trace!("Request {payload}");
Message::Binary(payload.into())
let payload = serialize(&payload).unwrap();
Message::Binary(payload)
};
if let Method::Authenticate
| Method::Invalidate

View file

@ -15,7 +15,7 @@ use crate::api::OnceLockExt;
use crate::api::Result;
use crate::api::Surreal;
use crate::engine::remote::ws::IntervalStream;
use crate::sql::serde::deserialize;
use crate::sql::serde::{deserialize, serialize};
use crate::sql::Strand;
use crate::sql::Value;
use flume::Receiver;
@ -146,7 +146,8 @@ pub(crate) fn router(
let mut request = BTreeMap::new();
request.insert("method".to_owned(), PING_METHOD.into());
let value = Value::from(request);
Message::Binary(value.into())
let value = serialize(&value).unwrap();
Message::Binary(value)
};
let mut vars = IndexMap::new();
@ -217,7 +218,8 @@ pub(crate) fn router(
}
let payload = Value::from(request);
trace!("Request {payload}");
Message::Binary(payload.into())
let payload = serialize(&payload).unwrap();
Message::Binary(payload)
};
if let Method::Authenticate
| Method::Invalidate

View file

@ -3,14 +3,15 @@ use crate::sql::object::Object;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use crate::vs::to_u128_be;
use derive::Store;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt::{self, Display, Formatter};
use derive::Store;
// Mutation is a single mutation to a table.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum TableMutation {
// Although the Value is supposed to contain a field "id" of Thing,
// we do include it in the first field for convenience.
@ -19,6 +20,7 @@ pub enum TableMutation {
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct TableMutations(pub String, pub Vec<TableMutation>);
impl TableMutations {
@ -28,6 +30,7 @@ impl TableMutations {
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DatabaseMutation(pub Vec<TableMutations>);
impl DatabaseMutation {
@ -43,6 +46,7 @@ impl Default for DatabaseMutation {
}
// Change is a set of mutations made to a table at the specific timestamp.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct ChangeSet(pub [u8; 10], pub DatabaseMutation);
impl TableMutation {
@ -123,6 +127,7 @@ impl Display for ChangeSet {
// WriteMutationSet is a set of mutations to be to a table at the specific timestamp.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct WriteMutationSet(pub Vec<TableMutations>);
impl WriteMutationSet {

View file

@ -50,7 +50,7 @@ impl SyncDistinct {
}
pub(super) fn check_already_processed(&mut self, pro: &Processed) -> bool {
if let Some(key) = pro.rid.as_ref().map(|rid| rid.to_vec()) {
if let Some(key) = pro.rid.as_ref().map(std::convert::Into::<Vec<u8>>::into) {
if self.processed.get(&key).is_some() {
true
} else {

View file

@ -1,4 +1,3 @@
use crate::cnf::PROTECTED_PARAM_NAMES;
use crate::ctx::Context;
use crate::dbs::response::Response;
use crate::dbs::Notification;
@ -260,7 +259,7 @@ impl<'a> Executor<'a> {
Ok(Value::None)
}
// Process param definition statements
Statement::Set(mut stm) => {
Statement::Set(stm) => {
// Create a transaction
let loc = self.begin(stm.writeable()).await;
// Check the transaction
@ -269,18 +268,8 @@ impl<'a> Executor<'a> {
true => Err(Error::TxFailure),
// The transaction began successfully
false => {
// Check if the variable is a protected variable
let res = match PROTECTED_PARAM_NAMES.contains(&stm.name.as_str()) {
// The variable isn't protected and can be stored
false => stm.compute(&ctx, &opt, &self.txn(), None).await,
// The user tried to set a protected variable
true => Err(Error::InvalidParam {
// Move the parameter name, as we no longer need it
name: std::mem::take(&mut stm.name),
}),
};
// Check the statement
match res {
match stm.compute(&ctx, &opt, &self.txn(), None).await {
Ok(val) => {
// Check if writeable
let writeable = stm.writeable();

View file

@ -1,6 +1,7 @@
use crate::err::Error;
use crate::err::Error::TimestampOverflow;
use derive::{Key, Store};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::ops::{Add, Sub};
use std::time::Duration;
@ -8,6 +9,7 @@ use std::time::Duration;
// NOTE: This is not a statement, but as per layering, keeping it here till we
// have a better structure.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize, PartialOrd, Hash, Store)]
#[revisioned(revision = 1)]
pub struct ClusterMembership {
pub name: String,
// TiKV = TiKV TSO Timestamp as u64
@ -18,12 +20,14 @@ pub struct ClusterMembership {
// events in a cluster. It should be derived from a timestamp oracle, such as the
// one available in TiKV via the client `TimestampExt` implementation.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize, PartialOrd, Hash, Store)]
#[revisioned(revision = 1)]
pub struct Timestamp {
pub value: u64,
}
// This struct is to be used only when storing keys as the macro currently
// conflicts when you have Store and Key derive macros.
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize, PartialOrd, Hash, Key)]
#[revisioned(revision = 1)]
pub struct KeyTimestamp {
pub value: u64,
}

View file

@ -5,11 +5,10 @@ use crate::sql::value::Value;
use crate::vs::Error as VersionstampError;
use base64_lib::DecodeError as Base64Error;
use bincode::Error as BincodeError;
use bung::encode::Error as SerdeError;
use fst::Error as FstError;
use jsonwebtoken::errors::Error as JWTError;
use revision::Error as RevisionError;
use serde::Serialize;
use std::borrow::Cow;
use std::io::Error as IoError;
use std::string::FromUtf8Error;
use storekey::decode::Error as DecodeError;
@ -33,6 +32,10 @@ pub enum Error {
#[error("{0}")]
Deprecated(String),
/// A custom error has been thrown
#[error("{0}")]
Thrown(String),
/// There was a problem with the underlying datastore
#[error("There was a problem with the underlying datastore: {0}")]
Ds(String),
@ -437,20 +440,20 @@ pub enum Error {
#[error("Expected a {into} but found {from}")]
CoerceTo {
from: Value,
into: Cow<'static, str>,
into: String,
},
/// Unable to convert a value to another value
#[error("Expected a {into} but cannot convert {from} into a {into}")]
ConvertTo {
from: Value,
into: Cow<'static, str>,
into: String,
},
/// Unable to coerce to a value to another value
#[error("Expected a {kind} but the array had {size} items")]
LengthInvalid {
kind: Cow<'static, str>,
kind: String,
size: usize,
},
@ -490,10 +493,6 @@ pub enum Error {
#[error("There was an error processing a value in parallel: {0}")]
Channel(String),
/// Represents an underlying error with Serde encoding / decoding
#[error("Serde error: {0}")]
Serde(#[from] SerdeError),
/// Represents an underlying error with IO encoding / decoding
#[error("I/O error: {0}")]
Io(#[from] IoError),
@ -506,6 +505,10 @@ pub enum Error {
#[error("Key decoding error: {0}")]
Decode(#[from] DecodeError),
/// Represents an underlying error with versioned data encoding / decoding
#[error("Versioned error: {0}")]
Revision(#[from] RevisionError),
/// The index has been found to be inconsistent
#[error("Index is corrupted")]
CorruptedIndex,

View file

@ -94,7 +94,7 @@ impl<'js> FromJs<'js> for QueryVariables {
impl Query {
#[qjs(constructor)]
pub fn new(ctx: Ctx<'_>, text: String, variables: Opt<QueryVariables>) -> Result<Self> {
let query = sql::sub_query(&text).map_err(|e| {
let query = sql::subquery(&text).map_err(|e| {
let error_text = format!("{}", e);
Exception::throw_type(&ctx, &error_text)
})?;

View file

@ -238,7 +238,7 @@ impl BKeys for FstKeys {
bincode::serialize_into(c, b)?;
Ok(())
} else {
Err(Error::Serde(ser::Error::custom(
Err(Error::Bincode(ser::Error::custom(
"bkeys.to_map() should be called prior serializing",
)))
}

View file

@ -2479,6 +2479,7 @@ impl Transaction {
// Private methods
// --------------------------------------------------
#[allow(unused_variables)]
fn check_level(&mut self, check: Check) {
match self {
#[cfg(feature = "kv-mem")]

View file

@ -2,10 +2,12 @@ use crate::sql::error::IResult;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Algorithm {
EdDSA,
Es256,

View file

@ -12,6 +12,7 @@ use crate::sql::value::{value, Value};
use nom::character::complete::char;
use nom::combinator::opt;
use nom::multi::separated_list0;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::fmt::{self, Display, Formatter, Write};
@ -23,6 +24,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Array";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Array")]
#[revisioned(revision = 1)]
pub struct Array(pub Vec<Value>);
impl From<Value> for Array {

View file

@ -4,10 +4,12 @@ use crate::sql::ident::{ident, Ident};
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Base {
Root,
Ns,

View file

@ -1,4 +1,3 @@
use crate::cnf::PROTECTED_PARAM_NAMES;
use crate::ctx::Context;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
@ -22,6 +21,7 @@ use nom::combinator::map;
use nom::multi::many0;
use nom::multi::separated_list0;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter, Write};
@ -31,6 +31,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Block";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Block")]
#[revisioned(revision = 1)]
pub struct Block(pub Vec<Entry>);
impl Deref for Block {
@ -65,18 +66,7 @@ impl Block {
for v in self.iter() {
match v {
Entry::Set(v) => {
// Check if the variable is a protected variable
let val = match PROTECTED_PARAM_NAMES.contains(&v.name.as_str()) {
// The variable isn't protected and can be stored
false => v.compute(&ctx, opt, txn, doc).await,
// The user tried to set a protected variable
true => {
return Err(Error::InvalidParam {
name: v.name.to_owned(),
})
}
}?;
// Set the parameter
let val = v.compute(&ctx, opt, txn, doc).await?;
ctx.add_value(v.name.to_owned(), val);
}
Entry::Ifelse(v) => {
@ -167,6 +157,7 @@ pub fn block(i: &str) -> IResult<&str, Block> {
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Entry {
Value(Value),
Set(SetStatement),

View file

@ -1,4 +1,5 @@
use base64_lib::{engine::general_purpose::STANDARD_NO_PAD, Engine};
use revision::revisioned;
use serde::{
de::{self, Visitor},
Deserialize, Serialize,
@ -7,6 +8,7 @@ use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Hash)]
#[revisioned(revision = 1)]
pub struct Bytes(pub(crate) Vec<u8>);
impl Bytes {

View file

@ -10,6 +10,7 @@ use crate::sql::value::{single, Value};
use async_recursion::async_recursion;
use nom::character::complete::char;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
@ -18,6 +19,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Cast";
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Cast")]
#[revisioned(revision = 1)]
pub struct Cast(pub Kind, pub Value);
impl PartialOrd for Cast {

View file

@ -2,12 +2,14 @@ use crate::sql::comment::shouldbespace;
use crate::sql::duration::{duration, Duration};
use crate::sql::error::IResult;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::str;
use std::time;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct ChangeFeed {
pub expiry: time::Duration,
}

View file

@ -2,11 +2,13 @@ use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
use crate::sql::value::{value, Value};
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Cond(pub Value);
impl Deref for Cond {

View file

@ -12,6 +12,7 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -19,6 +20,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Constant";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[serde(rename = "$surrealdb::private::sql::Constant")]
#[revisioned(revision = 1)]
pub enum Constant {
MathE,
MathFrac1Pi,

View file

@ -14,10 +14,12 @@ use crate::sql::value::{value, Value};
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Data {
EmptyExpression,
SetExpression(Vec<(Idiom, Operator, Value)>),

View file

@ -13,6 +13,7 @@ use nom::combinator::map;
use nom::error::ErrorKind;
use nom::sequence::delimited;
use nom::{error_position, Err};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops;
@ -24,6 +25,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Datetime";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Datetime")]
#[revisioned(revision = 1)]
pub struct Datetime(#[serde(with = "ts_binary")] pub DateTime<Utc>);
impl Default for Datetime {

View file

@ -1,10 +1,12 @@
use crate::sql::error::IResult;
use nom::branch::alt;
use nom::character::complete::char;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Dir {
In,
Out,

View file

@ -6,6 +6,7 @@ use crate::sql::strand::Strand;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::multi::many1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::iter::Sum;
@ -26,6 +27,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Duration";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Duration")]
#[revisioned(revision = 1)]
pub struct Duration(pub time::Duration);
impl From<time::Duration> for Duration {

View file

@ -6,6 +6,7 @@ use crate::sql::thing::{thing, Thing};
use nom::branch::alt;
use nom::character::complete::char;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -13,6 +14,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Edges";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Edges")]
#[revisioned(revision = 1)]
pub struct Edges {
pub dir: Dir,
pub from: Thing,

View file

@ -3,10 +3,12 @@ use crate::sql::error::IResult;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Explain(pub bool);
impl fmt::Display for Explain {

View file

@ -7,6 +7,7 @@ use crate::sql::comment::mightbespace;
use crate::sql::error::IResult;
use crate::sql::operator::{self, Operator};
use crate::sql::value::{single, value, Value};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str;
@ -16,6 +17,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Expression";
/// Binary expressions.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Expression")]
#[revisioned(revision = 1)]
pub enum Expression {
Unary {
o: Operator,

View file

@ -5,11 +5,13 @@ use crate::sql::fmt::Fmt;
use crate::sql::idiom::{plain as idiom, Idiom};
use nom::bytes::complete::tag_no_case;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Fetchs(pub Vec<Fetch>);
impl Deref for Fetchs {
@ -34,6 +36,7 @@ impl fmt::Display for Fetchs {
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Fetch(pub Idiom);
impl Deref for Fetch {

View file

@ -13,12 +13,14 @@ use crate::sql::value::{value, Value};
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::fmt::{self, Display, Formatter, Write};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Fields(pub Vec<Field>, pub bool);
impl Fields {
@ -203,6 +205,7 @@ fn field_many(i: &str) -> IResult<&str, Fields> {
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Field {
/// The `*` in `SELECT * FROM ...`
#[default]

View file

@ -6,11 +6,13 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::character::complete::u16;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Display;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Filter {
Ascii,
EdgeNgram(u16, u16),

View file

@ -21,6 +21,7 @@ use nom::combinator::recognize;
use nom::multi::separated_list0;
use nom::multi::separated_list1;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
@ -29,6 +30,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Function";
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Function")]
#[revisioned(revision = 1)]
pub enum Function {
Normal(String, Vec<Value>),
Custom(String, Vec<Value>),

View file

@ -8,6 +8,7 @@ use crate::sql::common::{closechevron, openchevron};
use crate::sql::error::IResult;
use crate::sql::value::Value;
use nom::bytes::complete::tag;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -15,6 +16,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Future";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Future")]
#[revisioned(revision = 1)]
pub struct Future(pub Block);
impl From<Value> for Future {

View file

@ -21,6 +21,7 @@ use nom::multi::separated_list1;
use nom::number::complete::double;
use nom::sequence::delimited;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::iter::{once, FromIterator};
@ -33,6 +34,7 @@ const DOUBLE: char = '\"';
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename = "$surrealdb::private::sql::Geometry")]
#[revisioned(revision = 1)]
pub enum Geometry {
Point(Point<f64>),
Line(LineString<f64>),

View file

@ -16,10 +16,12 @@ use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::combinator::map;
use nom::combinator::opt;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter, Write};
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Graph {
pub dir: Dir,
pub expr: Fields,

View file

@ -8,11 +8,13 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::multi::separated_list1;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Groups(pub Vec<Group>);
impl Deref for Groups {
@ -41,6 +43,7 @@ impl Display for Groups {
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Group(pub Idiom);
impl Deref for Group {

View file

@ -17,14 +17,15 @@ use crate::sql::value::Value;
use nanoid::nanoid;
use nom::branch::alt;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use ulid::Ulid;
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Id {
Number(i64),
/// Invariant: Doesn't contain NUL bytes.
String(String),
Array(Array),
Object(Object),

View file

@ -12,6 +12,7 @@ use nom::combinator::recognize;
use nom::combinator::value;
use nom::multi::separated_list1;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -25,6 +26,7 @@ const BACKTICK: char = '`';
const BACKTICK_ESC_NUL: &str = "`\\\0";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Ident(#[serde(with = "no_nul_bytes")] pub String);
impl From<String> for Ident {

View file

@ -15,6 +15,7 @@ use nom::branch::alt;
use nom::combinator::opt;
use nom::multi::separated_list1;
use nom::multi::{many0, many1};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -23,6 +24,7 @@ use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Idiom";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Idioms(pub Vec<Idiom>);
impl Deref for Idioms {
@ -45,6 +47,7 @@ pub fn locals(i: &str) -> IResult<&str, Idioms> {
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Idiom")]
#[revisioned(revision = 1)]
pub struct Idiom(pub Vec<Part>);
impl Deref for Idiom {

View file

@ -7,10 +7,12 @@ use nom::branch::alt;
use nom::bytes::complete::{tag, tag_no_case};
use nom::character::complete::u32;
use nom::combinator::{map, opt};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Index {
/// (Basic) non unique
Idx,

View file

@ -11,10 +11,12 @@ use nom::character::complete::u64;
use nom::combinator::map;
use nom::combinator::opt;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Kind {
Any,
Bool,

View file

@ -2,11 +2,13 @@ use crate::sql::error::IResult;
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Display;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Language {
Arabic,
Danish,

View file

@ -9,10 +9,12 @@ use crate::sql::value::{value, Value};
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Limit(pub Value);
impl Limit {

View file

@ -6,6 +6,7 @@ use crate::sql::ident::ident_raw;
use crate::sql::thing::Thing;
use nom::branch::alt;
use nom::character::complete::char;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -51,6 +52,7 @@ impl Iterator for IntoIter {
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Model")]
#[revisioned(revision = 1)]
pub enum Model {
Count(String, u64),
Range(String, u64, u64),

View file

@ -9,6 +9,7 @@ use nom::character::complete::i64;
use nom::combinator::{map, opt};
use nom::number::complete::recognize_float;
use nom::Err::Failure;
use revision::revisioned;
use rust_decimal::prelude::*;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
@ -23,6 +24,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Number";
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename = "$surrealdb::private::sql::Number")]
#[revisioned(revision = 1)]
pub enum Number {
Int(i64),
Float(f64),

View file

@ -17,6 +17,7 @@ use nom::character::complete::char;
use nom::combinator::opt;
use nom::multi::separated_list0;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::collections::HashMap;
@ -29,6 +30,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Object";
/// Invariant: Keys never contain NUL bytes.
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Object")]
#[revisioned(revision = 1)]
pub struct Object(#[serde(with = "no_nul_bytes_in_keys")] pub BTreeMap<String, Value>);
impl From<BTreeMap<String, Value>> for Object {

View file

@ -1,10 +1,12 @@
use crate::sql::idiom::Idiom;
use crate::sql::value::Value;
use revision::revisioned;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(tag = "op")]
#[serde(rename_all = "lowercase")]
#[revisioned(revision = 1)]
pub enum Operation {
Add {
path: Idiom,

View file

@ -8,12 +8,14 @@ use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::character::complete::u8 as uint8;
use nom::combinator::{map, opt};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Write;
/// Binary operators.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Operator {
//
Neg, // -

View file

@ -8,11 +8,13 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::{map, opt};
use nom::multi::separated_list1;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Orders(pub Vec<Order>);
impl Deref for Orders {
@ -37,6 +39,7 @@ impl fmt::Display for Orders {
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Order {
pub order: Idiom,
pub random: bool,

View file

@ -4,10 +4,12 @@ use crate::sql::field::{fields, Fields};
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Output {
None,
Null,

View file

@ -6,6 +6,7 @@ use crate::sql::error::IResult;
use crate::sql::ident::{ident, Ident};
use crate::sql::value::Value;
use nom::character::complete::char;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Deref;
@ -15,6 +16,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Param";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Param")]
#[revisioned(revision = 1)]
pub struct Param(pub Ident);
impl From<Ident> for Param {

View file

@ -3,7 +3,7 @@ use crate::iam::Error as IamError;
use crate::sql::error::Error::{Field, Group, Order, Parser, Role, Split};
use crate::sql::error::IResult;
use crate::sql::query::{query, Query};
use crate::sql::subquery::{subquery, Subquery};
use crate::sql::subquery::Subquery;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use nom::Err;
@ -16,12 +16,6 @@ pub fn parse(input: &str) -> Result<Query, Error> {
parse_impl(input, query)
}
/// Parses a SurrealQL Subquery [`Subquery`]
#[instrument(name = "parser", skip_all, fields(length = input.len()))]
pub fn sub_query(input: &str) -> Result<Subquery, Error> {
parse_impl(input, subquery)
}
/// Parses a SurrealQL [`Thing`]
#[instrument(name = "parser", skip_all, fields(length = input.len()))]
pub fn thing(input: &str) -> Result<Thing, Error> {
@ -34,6 +28,12 @@ pub fn value(input: &str) -> Result<Value, Error> {
parse_impl(input, super::value::value)
}
/// Parses a SurrealQL Subquery [`Subquery`]
#[instrument(name = "parser", skip_all, fields(length = input.len()))]
pub fn subquery(input: &str) -> Result<Subquery, Error> {
parse_impl(input, super::subquery::subquery)
}
/// Parses JSON into an inert SurrealQL [`Value`]
#[instrument(name = "parser", skip_all, fields(length = input.len()))]
pub fn json(input: &str) -> Result<Value, Error> {

View file

@ -15,11 +15,13 @@ use nom::bytes::complete::tag;
use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::combinator::{map, not, peek};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Part {
All,
Flatten,

View file

@ -10,12 +10,14 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use nom::{multi::separated_list0, sequence::tuple};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::Write;
use std::fmt::{self, Display, Formatter};
use std::str;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Permissions {
pub select: Permission,
pub create: Permission,
@ -181,6 +183,7 @@ fn specific(i: &str) -> IResult<&str, Permissions> {
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Permission {
None,
Full,

View file

@ -3,6 +3,7 @@ use crate::sql::fmt::Pretty;
use crate::sql::statement::{statements, Statement, Statements};
use derive::Store;
use nom::combinator::all_consuming;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::Write;
use std::fmt::{self, Display, Formatter};
@ -10,6 +11,7 @@ use std::ops::Deref;
use std::str;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct Query(pub Statements);
impl Deref for Query {

View file

@ -13,6 +13,7 @@ use nom::combinator::map;
use nom::combinator::opt;
use nom::sequence::preceded;
use nom::sequence::terminated;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
@ -23,6 +24,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Range";
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Range")]
#[revisioned(revision = 1)]
pub struct Range {
#[serde(with = "no_nul_bytes")]
pub tb: String,

View file

@ -3,6 +3,7 @@ use nom::bytes::complete::escaped;
use nom::bytes::complete::is_not;
use nom::character::complete::anychar;
use nom::character::complete::char;
use revision::revisioned;
use serde::{
de::{self, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
@ -17,7 +18,8 @@ use std::str::FromStr;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Regex";
#[derive(Clone)]
pub struct Regex(pub(super) regex::Regex);
#[revisioned(revision = 1)]
pub struct Regex(pub regex::Regex);
impl Regex {
// Deref would expose `regex::Regex::as_str` which wouldn't have the '/' delimiters.

View file

@ -6,11 +6,13 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use nom::number::complete::recognize_float;
use nom::Err::Failure;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::hash::{Hash, Hasher};
#[derive(Clone, Debug, Serialize, Deserialize)]
#[revisioned(revision = 1)]
pub enum Scoring {
Bm {
k1: f32,

View file

@ -7,6 +7,7 @@ use nom::character::complete::{anychar, char, multispace0};
use nom::combinator::recognize;
use nom::multi::{many0, many1};
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -25,6 +26,7 @@ const OBJECT_BEG: char = '{';
const OBJECT_END: char = '}';
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Script(#[serde(with = "no_nul_bytes")] pub String);
impl From<String> for Script {

View file

@ -7,11 +7,13 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::multi::separated_list1;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Splits(pub Vec<Split>);
impl Deref for Splits {
@ -36,6 +38,7 @@ impl fmt::Display for Splits {
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Split(pub Idiom);
impl Deref for Split {

View file

@ -9,10 +9,12 @@ use crate::sql::value::{value, Value};
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Start(pub Value);
impl Start {

View file

@ -14,6 +14,7 @@ use crate::sql::statements::commit::{commit, CommitStatement};
use crate::sql::statements::create::{create, CreateStatement};
use crate::sql::statements::define::{define, DefineStatement};
use crate::sql::statements::delete::{delete, DeleteStatement};
use crate::sql::statements::foreach::{foreach, ForeachStatement};
use crate::sql::statements::ifelse::{ifelse, IfelseStatement};
use crate::sql::statements::info::{info, InfoStatement};
use crate::sql::statements::insert::{insert, InsertStatement};
@ -21,14 +22,17 @@ use crate::sql::statements::kill::{kill, KillStatement};
use crate::sql::statements::live::{live, LiveStatement};
use crate::sql::statements::option::{option, OptionStatement};
use crate::sql::statements::output::{output, OutputStatement};
use crate::sql::statements::r#break::{r#break, BreakStatement};
use crate::sql::statements::r#continue::{r#continue, ContinueStatement};
use crate::sql::statements::r#use::{r#use, UseStatement};
use crate::sql::statements::relate::{relate, RelateStatement};
use crate::sql::statements::remove::{remove, RemoveStatement};
use crate::sql::statements::select::{select, SelectStatement};
use crate::sql::statements::set::{set, SetStatement};
use crate::sql::statements::show::{show, ShowStatement};
use crate::sql::statements::sleep::{sleep, SleepStatement};
use crate::sql::statements::throw::{throw, ThrowStatement};
use crate::sql::statements::update::{update, UpdateStatement};
use crate::sql::statements::yuse::{yuse, UseStatement};
use crate::sql::value::Value;
use derive::Store;
use nom::branch::alt;
@ -36,12 +40,14 @@ use nom::combinator::map;
use nom::multi::many0;
use nom::multi::separated_list1;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter, Write};
use std::ops::Deref;
use std::time::Duration;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct Statements(pub Vec<Statement>);
impl Deref for Statements {
@ -75,14 +81,18 @@ pub fn statements(i: &str) -> IResult<&str, Statements> {
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum Statement {
Analyze(AnalyzeStatement),
Begin(BeginStatement),
Break(BreakStatement),
Continue(ContinueStatement),
Cancel(CancelStatement),
Commit(CommitStatement),
Create(CreateStatement),
Define(DefineStatement),
Delete(DeleteStatement),
Foreach(ForeachStatement),
Ifelse(IfelseStatement),
Info(InfoStatement),
Insert(InsertStatement),
@ -97,6 +107,7 @@ pub enum Statement {
Show(ShowStatement),
Sleep(SleepStatement),
Update(UpdateStatement),
Throw(ThrowStatement),
Use(UseStatement),
}
@ -117,9 +128,12 @@ impl Statement {
pub(crate) fn writeable(&self) -> bool {
match self {
Self::Analyze(_) => false,
Self::Break(_) => false,
Self::Continue(_) => false,
Self::Create(v) => v.writeable(),
Self::Define(_) => true,
Self::Delete(v) => v.writeable(),
Self::Foreach(v) => v.writeable(),
Self::Ifelse(v) => v.writeable(),
Self::Info(_) => false,
Self::Insert(v) => v.writeable(),
@ -133,6 +147,7 @@ impl Statement {
Self::Set(v) => v.writeable(),
Self::Show(_) => false,
Self::Sleep(_) => false,
Self::Throw(_) => false,
Self::Update(v) => v.writeable(),
Self::Use(_) => false,
_ => unreachable!(),
@ -148,9 +163,12 @@ impl Statement {
) -> Result<Value, Error> {
match self {
Self::Analyze(v) => v.compute(ctx, opt, txn, doc).await,
Self::Break(v) => v.compute(ctx, opt, txn, doc).await,
Self::Continue(v) => v.compute(ctx, opt, txn, doc).await,
Self::Create(v) => v.compute(ctx, opt, txn, doc).await,
Self::Delete(v) => v.compute(ctx, opt, txn, doc).await,
Self::Define(v) => v.compute(ctx, opt, txn, doc).await,
Self::Foreach(v) => v.compute(ctx, opt, txn, doc).await,
Self::Ifelse(v) => v.compute(ctx, opt, txn, doc).await,
Self::Info(v) => v.compute(ctx, opt, txn, doc).await,
Self::Insert(v) => v.compute(ctx, opt, txn, doc).await,
@ -162,7 +180,8 @@ impl Statement {
Self::Select(v) => v.compute(ctx, opt, txn, doc).await,
Self::Set(v) => v.compute(ctx, opt, txn, doc).await,
Self::Show(v) => v.compute(ctx, opt, txn, doc).await,
Self::Sleep(v) => v.compute(ctx, opt, doc).await,
Self::Sleep(v) => v.compute(ctx, opt, txn, doc).await,
Self::Throw(v) => v.compute(ctx, opt, txn, doc).await,
Self::Update(v) => v.compute(ctx, opt, txn, doc).await,
_ => unreachable!(),
}
@ -174,11 +193,14 @@ impl Display for Statement {
match self {
Self::Analyze(v) => write!(Pretty::from(f), "{v}"),
Self::Begin(v) => write!(Pretty::from(f), "{v}"),
Self::Break(v) => write!(Pretty::from(f), "{v}"),
Self::Cancel(v) => write!(Pretty::from(f), "{v}"),
Self::Commit(v) => write!(Pretty::from(f), "{v}"),
Self::Continue(v) => write!(Pretty::from(f), "{v}"),
Self::Create(v) => write!(Pretty::from(f), "{v}"),
Self::Define(v) => write!(Pretty::from(f), "{v}"),
Self::Delete(v) => write!(Pretty::from(f), "{v}"),
Self::Foreach(v) => write!(Pretty::from(f), "{v}"),
Self::Insert(v) => write!(Pretty::from(f), "{v}"),
Self::Ifelse(v) => write!(Pretty::from(f), "{v}"),
Self::Info(v) => write!(Pretty::from(f), "{v}"),
@ -192,6 +214,7 @@ impl Display for Statement {
Self::Set(v) => write!(Pretty::from(f), "{v}"),
Self::Show(v) => write!(Pretty::from(f), "{v}"),
Self::Sleep(v) => write!(Pretty::from(f), "{v}"),
Self::Throw(v) => write!(Pretty::from(f), "{v}"),
Self::Update(v) => write!(Pretty::from(f), "{v}"),
Self::Use(v) => write!(Pretty::from(f), "{v}"),
}
@ -202,27 +225,36 @@ pub fn statement(i: &str) -> IResult<&str, Statement> {
delimited(
mightbespace,
alt((
map(analyze, Statement::Analyze),
map(begin, Statement::Begin),
map(cancel, Statement::Cancel),
map(commit, Statement::Commit),
map(create, Statement::Create),
map(define, Statement::Define),
map(delete, Statement::Delete),
map(ifelse, Statement::Ifelse),
map(info, Statement::Info),
map(insert, Statement::Insert),
map(kill, Statement::Kill),
map(live, Statement::Live),
map(option, Statement::Option),
map(output, Statement::Output),
map(relate, Statement::Relate),
map(remove, Statement::Remove),
map(select, Statement::Select),
map(set, Statement::Set),
map(show, Statement::Show),
map(sleep, Statement::Sleep),
alt((map(update, Statement::Update), map(yuse, Statement::Use))),
alt((
map(analyze, Statement::Analyze),
map(begin, Statement::Begin),
map(r#break, Statement::Break),
map(cancel, Statement::Cancel),
map(commit, Statement::Commit),
map(r#continue, Statement::Continue),
map(create, Statement::Create),
map(define, Statement::Define),
map(delete, Statement::Delete),
map(foreach, Statement::Foreach),
map(ifelse, Statement::Ifelse),
map(info, Statement::Info),
map(insert, Statement::Insert),
)),
alt((
map(kill, Statement::Kill),
map(live, Statement::Live),
map(option, Statement::Option),
map(output, Statement::Output),
map(relate, Statement::Relate),
map(remove, Statement::Remove),
map(select, Statement::Select),
map(set, Statement::Set),
map(show, Statement::Show),
map(sleep, Statement::Sleep),
map(throw, Statement::Throw),
map(update, Statement::Update),
map(r#use, Statement::Use),
)),
)),
mightbespace,
)(i)

View file

@ -15,11 +15,13 @@ use crate::sql::value::Value;
use crate::sql::Base;
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum AnalyzeStatement {
Idx(Ident, Ident),
}

View file

@ -5,10 +5,12 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct BeginStatement;
impl fmt::Display for BeginStatement {

View file

@ -0,0 +1,56 @@
use crate::ctx::Context;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::sql::error::IResult;
use crate::sql::value::Value;
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct BreakStatement;
impl BreakStatement {
/// Process this type returning a computed simple Value
pub(crate) async fn compute(
&self,
_ctx: &Context<'_>,
_opt: &Options,
_txn: &Transaction,
_doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
Err(Error::FeatureNotYetImplemented {
feature: "BREAK statements",
})
}
}
impl fmt::Display for BreakStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("BREAK")
}
}
pub fn r#break(i: &str) -> IResult<&str, BreakStatement> {
let (i, _) = tag_no_case("BREAK")(i)?;
Ok((i, BreakStatement))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn break_basic() {
let sql = "BREAK";
let res = r#break(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("BREAK", format!("{}", out))
}
}

View file

@ -5,10 +5,12 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct CancelStatement;
impl fmt::Display for CancelStatement {

View file

@ -5,10 +5,12 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct CommitStatement;
impl fmt::Display for CommitStatement {

View file

@ -0,0 +1,56 @@
use crate::ctx::Context;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::sql::error::IResult;
use crate::sql::value::Value;
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct ContinueStatement;
impl ContinueStatement {
/// Process this type returning a computed simple Value
pub(crate) async fn compute(
&self,
_ctx: &Context<'_>,
_opt: &Options,
_txn: &Transaction,
_doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
Err(Error::FeatureNotYetImplemented {
feature: "CONTINUE statements",
})
}
}
impl fmt::Display for ContinueStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("CONTINUE")
}
}
pub fn r#continue(i: &str) -> IResult<&str, ContinueStatement> {
let (i, _) = tag_no_case("CONTINUE")(i)?;
Ok((i, ContinueStatement))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn continue_basic() {
let sql = "CONTINUE";
let res = r#continue(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("CONTINUE", format!("{}", out))
}
}

View file

@ -15,10 +15,12 @@ use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct CreateStatement {
pub what: Values,
pub data: Option<Data>,

View file

@ -47,10 +47,12 @@ use nom::Err::Failure;
use rand::distributions::Alphanumeric;
use rand::rngs::OsRng;
use rand::Rng;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Write};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum DefineStatement {
Namespace(DefineNamespaceStatement),
Database(DefineDatabaseStatement),
@ -139,6 +141,7 @@ pub fn define(i: &str) -> IResult<&str, DefineStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineNamespaceStatement {
pub name: Ident,
}
@ -189,6 +192,7 @@ fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineDatabaseStatement {
pub name: Ident,
pub changefeed: Option<ChangeFeed>,
@ -267,6 +271,7 @@ fn database_opts(i: &str) -> IResult<&str, DefineDatabaseOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineFunctionStatement {
pub name: Ident,
pub args: Vec<(Ident, Kind)>,
@ -348,6 +353,7 @@ fn function(i: &str) -> IResult<&str, DefineFunctionStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineAnalyzerStatement {
pub name: Ident,
pub tokenizers: Option<Vec<Tokenizer>>,
@ -418,6 +424,7 @@ pub(crate) fn analyzer(i: &str) -> IResult<&str, DefineAnalyzerStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineLoginStatement {
pub name: Ident,
pub base: Base,
@ -494,6 +501,7 @@ fn login_hash(i: &str) -> IResult<&str, DefineLoginOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineUserStatement {
pub name: Ident,
pub base: Base,
@ -676,6 +684,7 @@ fn user_roles(i: &str) -> IResult<&str, DefineUserOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineTokenStatement {
pub name: Ident,
pub base: Base,
@ -781,6 +790,7 @@ fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineScopeStatement {
pub name: Ident,
pub code: String,
@ -900,6 +910,7 @@ fn scope_signin(i: &str) -> IResult<&str, DefineScopeOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineParamStatement {
pub name: Ident,
pub value: Value,
@ -959,6 +970,7 @@ fn param(i: &str) -> IResult<&str, DefineParamStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineTableStatement {
pub name: Ident,
pub drop: bool,
@ -1161,6 +1173,7 @@ fn table_permissions(i: &str) -> IResult<&str, DefineTableOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineEventStatement {
pub name: Ident,
pub what: Ident,
@ -1240,6 +1253,7 @@ fn event(i: &str) -> IResult<&str, DefineEventStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineFieldStatement {
pub name: Idiom,
pub what: Ident,
@ -1247,6 +1261,7 @@ pub struct DefineFieldStatement {
pub kind: Option<Kind>,
pub value: Option<Value>,
pub assert: Option<Value>,
pub default: Option<Value>,
pub permissions: Permissions,
}
@ -1336,6 +1351,10 @@ fn field(i: &str) -> IResult<&str, DefineFieldStatement> {
DefineFieldOption::Assert(ref v) => Some(v.to_owned()),
_ => None,
}),
default: opts.iter().find_map(|x| match x {
DefineFieldOption::Default(ref v) => Some(v.to_owned()),
_ => None,
}),
permissions: opts
.iter()
.find_map(|x| match x {
@ -1353,11 +1372,12 @@ pub enum DefineFieldOption {
Kind(Kind),
Value(Value),
Assert(Value),
Default(Value),
Permissions(Permissions),
}
fn field_opts(i: &str) -> IResult<&str, DefineFieldOption> {
alt((field_flex, field_kind, field_value, field_assert, field_permissions))(i)
alt((field_flex, field_kind, field_value, field_assert, field_default, field_permissions))(i)
}
fn field_flex(i: &str) -> IResult<&str, DefineFieldOption> {
@ -1390,6 +1410,14 @@ fn field_assert(i: &str) -> IResult<&str, DefineFieldOption> {
Ok((i, DefineFieldOption::Assert(v)))
}
fn field_default(i: &str) -> IResult<&str, DefineFieldOption> {
let (i, _) = shouldbespace(i)?;
let (i, _) = tag_no_case("DEFAULT")(i)?;
let (i, _) = shouldbespace(i)?;
let (i, v) = value(i)?;
Ok((i, DefineFieldOption::Default(v)))
}
fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> {
let (i, _) = shouldbespace(i)?;
let (i, v) = permissions(i)?;
@ -1401,6 +1429,7 @@ fn field_permissions(i: &str) -> IResult<&str, DefineFieldOption> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DefineIndexStatement {
pub name: Ident,
pub what: Ident,
@ -1503,7 +1532,8 @@ mod tests {
let stm = DefineStatement::Namespace(DefineNamespaceStatement {
name: Ident::from("test"),
});
assert_eq!(6, stm.to_vec().len());
let enc: Vec<u8> = stm.try_into().unwrap();
assert_eq!(9, enc.len());
}
#[test]
@ -1595,9 +1625,9 @@ mod tests {
let out = res.unwrap().1;
assert_eq!(sql, format!("{}", out));
let serialized = out.to_vec();
let deserializled = DefineDatabaseStatement::try_from(&serialized).unwrap();
assert_eq!(out, deserializled);
let serialized: Vec<u8> = (&out).try_into().unwrap();
let deserialized = DefineDatabaseStatement::try_from(&serialized).unwrap();
assert_eq!(out, deserialized);
}
#[test]
@ -1608,8 +1638,8 @@ mod tests {
let out = res.unwrap().1;
assert_eq!(sql, format!("{}", out));
let serialized = out.to_vec();
let deserializled = DefineTableStatement::try_from(&serialized).unwrap();
assert_eq!(out, deserializled);
let serialized: Vec<u8> = (&out).try_into().unwrap();
let deserialized = DefineTableStatement::try_from(&serialized).unwrap();
assert_eq!(out, deserialized);
}
}

View file

@ -16,10 +16,12 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct DeleteStatement {
pub what: Values,
pub cond: Option<Cond>,

View file

@ -0,0 +1,82 @@
use crate::ctx::Context;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::sql::block::{block, Block};
use crate::sql::comment::{mightbespace, shouldbespace};
use crate::sql::error::IResult;
use crate::sql::param::{param, Param};
use crate::sql::value::{value, Value};
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct ForeachStatement {
pub param: Param,
pub range: Value,
pub block: Block,
}
impl ForeachStatement {
/// Check if we require a writeable transaction
pub(crate) fn writeable(&self) -> bool {
self.range.writeable() || self.block.writeable()
}
/// Process this type returning a computed simple Value
pub(crate) async fn compute(
&self,
_ctx: &Context<'_>,
_opt: &Options,
_txn: &Transaction,
_doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
Err(Error::FeatureNotYetImplemented {
feature: "FOR statements",
})
}
}
impl Display for ForeachStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FOR {} IN {} {}", self.param, self.range, self.block)
}
}
pub fn foreach(i: &str) -> IResult<&str, ForeachStatement> {
let (i, _) = tag_no_case("FOR")(i)?;
let (i, _) = shouldbespace(i)?;
let (i, param) = param(i)?;
let (i, _) = shouldbespace(i)?;
let (i, _) = tag_no_case("IN")(i)?;
let (i, _) = shouldbespace(i)?;
let (i, range) = value(i)?;
let (i, _) = mightbespace(i)?;
let (i, block) = block(i)?;
Ok((
i,
ForeachStatement {
param,
range,
block,
},
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn foreach_statement_first() {
let sql = "FOR $test IN [1, 2, 3, 4, 5] { UPDATE person:test SET scores += $test; }";
let res = foreach(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!(sql, format!("{}", out))
}
}

View file

@ -10,10 +10,12 @@ use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::multi::separated_list0;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Write};
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct IfelseStatement {
pub exprs: Vec<(Value, Value)>,
pub close: Option<Value>,

View file

@ -16,10 +16,12 @@ use derive::Store;
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum InfoStatement {
Root,
Ns,

View file

@ -18,10 +18,12 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::{map, opt};
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct InsertStatement {
pub into: Value,
pub data: Data,

View file

@ -12,10 +12,12 @@ use derive::Store;
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct KillStatement {
// Uuid of Live Query
// or Param resolving to Uuid of Live Query

View file

@ -18,10 +18,12 @@ use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct LiveStatement {
pub id: Uuid,
pub node: Uuid,

View file

@ -1,10 +1,13 @@
pub(crate) mod analyze;
pub(crate) mod begin;
pub(crate) mod r#break;
pub(crate) mod cancel;
pub(crate) mod commit;
pub(crate) mod r#continue;
pub(crate) mod create;
pub(crate) mod define;
pub(crate) mod delete;
pub(crate) mod foreach;
pub(crate) mod ifelse;
pub(crate) mod info;
pub(crate) mod insert;
@ -18,14 +21,16 @@ pub(crate) mod select;
pub(crate) mod set;
pub(crate) mod show;
pub(crate) mod sleep;
pub(crate) mod throw;
pub(crate) mod update;
pub(crate) mod yuse;
pub(crate) mod r#use;
pub use self::begin::BeginStatement;
pub use self::cancel::CancelStatement;
pub use self::commit::CommitStatement;
pub use self::create::CreateStatement;
pub use self::delete::DeleteStatement;
pub use self::foreach::ForeachStatement;
pub use self::ifelse::IfelseStatement;
pub use self::info::InfoStatement;
pub use self::insert::InsertStatement;
@ -33,11 +38,14 @@ pub use self::kill::KillStatement;
pub use self::live::LiveStatement;
pub use self::option::OptionStatement;
pub use self::output::OutputStatement;
pub use self::r#break::BreakStatement;
pub use self::r#continue::ContinueStatement;
pub use self::r#use::UseStatement;
pub use self::relate::RelateStatement;
pub use self::select::SelectStatement;
pub use self::set::SetStatement;
pub use self::throw::ThrowStatement;
pub use self::update::UpdateStatement;
pub use self::yuse::UseStatement;
pub use self::define::DefineAnalyzerStatement;
pub use self::define::DefineDatabaseStatement;

View file

@ -8,10 +8,12 @@ use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::combinator::{map, opt};
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct OptionStatement {
pub name: Ident,
pub what: bool,

View file

@ -10,10 +10,12 @@ use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct OutputStatement {
pub what: Value,
pub fetch: Option<Fetchs>,

View file

@ -24,10 +24,12 @@ use nom::character::complete::char;
use nom::combinator::map;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RelateStatement {
pub kind: Value,
pub from: Value,

View file

@ -19,10 +19,12 @@ use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::combinator::{map, opt};
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub enum RemoveStatement {
Namespace(RemoveNamespaceStatement),
Database(RemoveDatabaseStatement),
@ -109,6 +111,7 @@ pub fn remove(i: &str) -> IResult<&str, RemoveStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveNamespaceStatement {
pub name: Ident,
}
@ -161,6 +164,7 @@ fn namespace(i: &str) -> IResult<&str, RemoveNamespaceStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveDatabaseStatement {
pub name: Ident,
}
@ -213,6 +217,7 @@ fn database(i: &str) -> IResult<&str, RemoveDatabaseStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveFunctionStatement {
pub name: Ident,
}
@ -270,6 +275,7 @@ fn function(i: &str) -> IResult<&str, RemoveFunctionStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveAnalyzerStatement {
pub name: Ident,
}
@ -319,6 +325,7 @@ fn analyzer(i: &str) -> IResult<&str, RemoveAnalyzerStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveLoginStatement {
pub name: Ident,
pub base: Base,
@ -389,6 +396,7 @@ fn login(i: &str) -> IResult<&str, RemoveLoginStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveTokenStatement {
pub name: Ident,
pub base: Base,
@ -468,6 +476,7 @@ fn token(i: &str) -> IResult<&str, RemoveTokenStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveScopeStatement {
pub name: Ident,
}
@ -520,6 +529,7 @@ fn scope(i: &str) -> IResult<&str, RemoveScopeStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveParamStatement {
pub name: Ident,
}
@ -570,6 +580,7 @@ fn param(i: &str) -> IResult<&str, RemoveParamStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveTableStatement {
pub name: Ident,
}
@ -622,6 +633,7 @@ fn table(i: &str) -> IResult<&str, RemoveTableStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveEventStatement {
pub name: Ident,
pub what: Ident,
@ -681,6 +693,7 @@ fn event(i: &str) -> IResult<&str, RemoveEventStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveFieldStatement {
pub name: Idiom,
pub what: Ident,
@ -741,6 +754,7 @@ fn field(i: &str) -> IResult<&str, RemoveFieldStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct RemoveIndexStatement {
pub name: Ident,
pub what: Ident,
@ -803,7 +817,7 @@ fn index(i: &str) -> IResult<&str, RemoveIndexStatement> {
// --------------------------------------------------
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[format(Named)]
#[revisioned(revision = 1)]
pub struct RemoveUserStatement {
pub name: Ident,
pub base: Base,
@ -888,6 +902,7 @@ mod tests {
let stm = RemoveStatement::Namespace(RemoveNamespaceStatement {
name: Ident::from("test"),
});
assert_eq!(6, stm.to_vec().len());
let enc: Vec<u8> = stm.try_into().unwrap();
assert_eq!(9, enc.len());
}
}

View file

@ -28,10 +28,12 @@ use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct SelectStatement {
pub expr: Fields,
pub what: Values,

View file

@ -1,3 +1,4 @@
use crate::cnf::PROTECTED_PARAM_NAMES;
use crate::ctx::Context;
use crate::dbs::Options;
use crate::dbs::Transaction;
@ -11,11 +12,14 @@ use crate::sql::value::{value, Value};
use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::character::complete::char;
use nom::sequence::preceded;
use nom::combinator::opt;
use nom::sequence::{preceded, terminated};
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct SetStatement {
pub name: String,
pub what: Value,
@ -34,7 +38,16 @@ impl SetStatement {
txn: &Transaction,
doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
self.what.compute(ctx, opt, txn, doc).await
// Check if the variable is a protected variable
match PROTECTED_PARAM_NAMES.contains(&self.name.as_str()) {
// The variable isn't protected and can be stored
false => self.what.compute(ctx, opt, txn, doc).await,
// The user tried to set a protected variable
true => Err(Error::InvalidParam {
// Move the parameter name, as we no longer need it
name: self.name.to_owned(),
}),
}
}
}
@ -45,8 +58,7 @@ impl fmt::Display for SetStatement {
}
pub fn set(i: &str) -> IResult<&str, SetStatement> {
let (i, _) = tag_no_case("LET")(i)?;
let (i, _) = shouldbespace(i)?;
let (i, _) = opt(terminated(tag_no_case("LET"), shouldbespace))(i)?;
let (i, n) = preceded(char('$'), ident_raw)(i)?;
let (i, _) = mightbespace(i)?;
let (i, _) = char('=')(i)?;

View file

@ -18,12 +18,14 @@ use nom::character::complete::u32;
use nom::combinator::map;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
// ShowStatement is used to show changes in a table or database via
// the SHOW CHANGES statement.
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct ShowStatement {
pub table: Option<Table>,
pub since: Option<u64>,

View file

@ -1,5 +1,5 @@
use crate::ctx::Context;
use crate::dbs::Options;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::iam::{Action, ResourceKind};
@ -9,10 +9,12 @@ use crate::sql::error::IResult;
use crate::sql::{Base, Duration, Value};
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct SleepStatement {
duration: Duration,
}
@ -23,6 +25,7 @@ impl SleepStatement {
&self,
ctx: &Context<'_>,
opt: &Options,
_txn: &Transaction,
_doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
// Allowed to run?
@ -64,8 +67,6 @@ pub fn sleep(i: &str) -> IResult<&str, SleepStatement> {
mod tests {
use super::*;
use crate::dbs::test::mock;
use crate::iam::{Auth, Role};
use std::sync::Arc;
use std::time::SystemTime;
#[test]
@ -90,10 +91,9 @@ mod tests {
async fn test_sleep_compute() {
let sql = "SLEEP 500ms";
let time = SystemTime::now();
let opt = Options::default().with_auth(Arc::new(Auth::for_root(Role::Owner)));
let (ctx, _, _) = mock().await;
let (ctx, opt, txn) = mock().await;
let (_, stm) = sleep(sql).unwrap();
let value = stm.compute(&ctx, &opt, None).await.unwrap();
let value = stm.compute(&ctx, &opt, &txn, None).await.unwrap();
assert!(time.elapsed().unwrap() >= time::Duration::microseconds(500));
assert_eq!(value, Value::None);
}

View file

@ -0,0 +1,58 @@
use crate::ctx::Context;
use crate::dbs::{Options, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::sql::comment::shouldbespace;
use crate::sql::error::IResult;
use crate::sql::strand::{strand, Strand};
use crate::sql::value::Value;
use derive::Store;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct ThrowStatement(pub Strand);
impl ThrowStatement {
/// Process this type returning a computed simple Value
pub(crate) async fn compute(
&self,
_ctx: &Context<'_>,
_opt: &Options,
_txn: &Transaction,
_doc: Option<&CursorDoc<'_>>,
) -> Result<Value, Error> {
Err(Error::Thrown(self.0.as_str().to_owned()))
}
}
impl fmt::Display for ThrowStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "THROW {}", self.0)
}
}
pub fn throw(i: &str) -> IResult<&str, ThrowStatement> {
let (i, _) = tag_no_case("THROW")(i)?;
let (i, _) = shouldbespace(i)?;
let (i, e) = strand(i)?;
Ok((i, ThrowStatement(e)))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn throw_basic() {
let sql = "THROW 'Record does not exist'";
let res = throw(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("THROW 'Record does not exist'", format!("{}", out))
}
}

View file

@ -16,10 +16,12 @@ use derive::Store;
use nom::bytes::complete::tag_no_case;
use nom::combinator::opt;
use nom::sequence::preceded;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct UpdateStatement {
pub what: Values,
pub data: Option<Data>,

View file

@ -4,10 +4,12 @@ use crate::sql::ident::ident_raw;
use derive::Store;
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize, Store, Hash)]
#[revisioned(revision = 1)]
pub struct UseStatement {
pub ns: Option<String>,
pub db: Option<String>,
@ -26,7 +28,7 @@ impl fmt::Display for UseStatement {
}
}
pub fn yuse(i: &str) -> IResult<&str, UseStatement> {
pub fn r#use(i: &str) -> IResult<&str, UseStatement> {
alt((both, ns, db))(i)
}
@ -87,7 +89,7 @@ mod tests {
#[test]
fn use_query_ns() {
let sql = "USE NS test";
let res = yuse(sql);
let res = r#use(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!(
@ -103,7 +105,7 @@ mod tests {
#[test]
fn use_query_db() {
let sql = "USE DB test";
let res = yuse(sql);
let res = r#use(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!(
@ -119,7 +121,7 @@ mod tests {
#[test]
fn use_query_both() {
let sql = "USE NS test DB test";
let res = yuse(sql);
let res = r#use(sql);
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!(

View file

@ -7,6 +7,7 @@ use nom::character::complete::char;
use nom::combinator::value;
use nom::sequence::preceded;
use nom::Err::Failure;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -27,6 +28,7 @@ const TRAILING_SURROGATES: RangeInclusive<u16> = 0xDC00..=0xDFFF;
/// A string that doesn't contain NUL bytes.
#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Strand")]
#[revisioned(revision = 1)]
pub struct Strand(#[serde(with = "no_nul_bytes")] pub String);
impl From<String> for Strand {

View file

@ -16,6 +16,7 @@ use crate::sql::statements::update::{update, UpdateStatement};
use crate::sql::value::{value, Value};
use nom::branch::alt;
use nom::combinator::map;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter};
@ -24,6 +25,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Subquery";
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Subquery")]
#[revisioned(revision = 1)]
pub enum Subquery {
Value(Value),
Ifelse(IfelseStatement),

View file

@ -7,6 +7,7 @@ use crate::sql::ident::{ident_raw, Ident};
use crate::sql::strand::no_nul_bytes;
use crate::sql::thing::Thing;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -15,6 +16,7 @@ use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Table";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Tables(pub Vec<Table>);
impl From<Table> for Tables {
@ -43,6 +45,7 @@ pub fn tables(i: &str) -> IResult<&str, Tables> {
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Table")]
#[revisioned(revision = 1)]
pub struct Table(#[serde(with = "no_nul_bytes")] pub String);
impl From<String> for Table {

View file

@ -14,6 +14,7 @@ use nom::bytes::complete::tag;
use nom::character::complete::char;
use nom::combinator::map;
use nom::sequence::delimited;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
@ -22,6 +23,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Thing";
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Store, Hash)]
#[serde(rename = "$surrealdb::private::sql::Thing")]
#[revisioned(revision = 1)]
pub struct Thing {
pub tb: String,
pub id: Id,

View file

@ -2,11 +2,13 @@ use crate::sql::comment::shouldbespace;
use crate::sql::duration::{duration, Duration};
use crate::sql::error::IResult;
use nom::bytes::complete::tag_no_case;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub struct Timeout(pub Duration);
impl Deref for Timeout {

View file

@ -5,11 +5,13 @@ use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use nom::multi::separated_list1;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Display;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
#[revisioned(revision = 1)]
pub enum Tokenizer {
Blank,
Camel,

View file

@ -8,6 +8,7 @@ use nom::character::complete::char;
use nom::combinator::recognize;
use nom::sequence::delimited;
use nom::sequence::tuple;
use revision::revisioned;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
@ -18,6 +19,7 @@ pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Uuid";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[serde(rename = "$surrealdb::private::sql::Uuid")]
#[revisioned(revision = 1)]
pub struct Uuid(#[serde(with = "uuid::serde::compact")] pub uuid::Uuid);
impl From<uuid::Uuid> for Uuid {

View file

@ -5,9 +5,9 @@ impl Value {
pub(crate) fn merge(&mut self, val: Value) -> Result<(), Error> {
if val.is_object() {
for k in val.every(None, false, false).iter() {
match val.pick(&k.0) {
Value::None => self.cut(&k.0),
v => self.put(&k.0, v),
match val.pick(k) {
Value::None => self.cut(k),
v => self.put(k, v),
}
}
}

Some files were not shown because too many files have changed in this diff Show more