Skip to content

Commit

Permalink
Merge branch 'main' into dima/include-session-in-live-query
Browse files Browse the repository at this point in the history
# Conflicts:
#	core/src/fnc/mod.rs
  • Loading branch information
blaginin committed Aug 22, 2024
2 parents 291bc60 + 898d75b commit 50e53f6
Show file tree
Hide file tree
Showing 207 changed files with 82 additions and 33 deletions.
4 changes: 2 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ Makefile.* @surrealdb/ci
Cargo.lock @surrealdb/security
Cargo.toml @surrealdb/security
core/Cargo.toml @surrealdb/security
lib/Cargo.toml @surrealdb/security
sdk/Cargo.toml @surrealdb/security
cackle.toml @surrealdb/security
supply-chain/* @surrealdb/security
deny.toml @surrealdb/security

# Code for fuzzing configuration
/lib/fuzz/ @surrealdb/security
/sdk/fuzz/ @surrealdb/security
SECURITY.md @surrealdb/security

# Code and tests for indexing
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
save-if: ${{ github.ref == 'refs/heads/main' }}

- name: Check fuzzers
run: cargo build --manifest-path lib/fuzz/Cargo.toml
run: cargo build --manifest-path sdk/fuzz/Cargo.toml

- name: Check OSS-Fuzz
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
Expand Down
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ storage-fdb-7_3 = ["surrealdb-core/kv-fdb-7_3"]
[workspace]
members = [
"core",
"lib",
"lib/examples/actix",
"lib/examples/axum",
"lib/examples/rocket",
"sdk",
"sdk/examples/actix",
"sdk/examples/axum",
"sdk/examples/rocket",
]

[profile.release]
Expand Down Expand Up @@ -118,7 +118,7 @@ semver = "1.0.20"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
serde_pack = { version = "1.1.2", package = "rmp-serde" }
surrealdb = { version = "2", path = "lib", features = [
surrealdb = { version = "2", path = "sdk", features = [
"protocol-http",
"protocol-ws",
"rustls",
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const BUILD_METADATA: &str = "SURREAL_BUILD_METADATA";

fn main() {
println!("cargo:rerun-if-env-changed={BUILD_METADATA}");
println!("cargo:rerun-if-changed=lib");
println!("cargo:rerun-if-changed=sdk");
println!("cargo:rerun-if-changed=src");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ publish = true
edition = "2021"
version = "2.0.0"
rust-version = "1.77.0"
readme = "../lib/CARGO.md"
readme = "../sdk/CARGO.md"
authors = ["Tobie Morgan Hitchcock <[email protected]>"]
description = "A scalable, distributed, collaborative, document-graph database, for the realtime web"
repository = "https://github.com/surrealdb/surrealdb"
Expand Down
2 changes: 1 addition & 1 deletion core/src/fnc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ mod tests {
for problem in problems {
eprintln!(" - {problem}");
}
panic!("ensure functions can be parsed in lib/src/sql/function.rs and are exported to JS in ./core/src/fnc/script/modules/surrealdb");
panic!("ensure functions can be parsed in core/src/sql/function.rs and are exported to JS in core/src/fnc/script/modules/surrealdb");
}
}
}
3 changes: 3 additions & 0 deletions core/src/gql/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ fn kind_to_type(kind: Kind, types: &mut Vec<Type>) -> Result<TypeRef, GqlError>
Kind::Array(k, _) => TypeRef::List(Box::new(kind_to_type(*k, types)?)),
Kind::Function(_, _) => return Err(schema_error("Kind::Function is not yet supported")),
Kind::Range => return Err(schema_error("Kind::Range is not yet supported")),
Kind::Literal(_) => return Err(schema_error("Kind::Literal is not yet supported")),
};

let out = match optional {
Expand Down Expand Up @@ -672,6 +673,7 @@ fn filter_from_type(
Kind::Array(_, _) => {}
Kind::Function(_, _) => {}
Kind::Range => {}
Kind::Literal(_) => {}
};
Ok(filter)
}
Expand Down Expand Up @@ -1113,5 +1115,6 @@ fn gql_to_sql_kind(val: &GqlValue, kind: Kind) -> Result<SqlValue, GqlError> {
},
Kind::Function(_, _) => Err(resolver_error("Sets are not yet supported")),
Kind::Range => Err(resolver_error("Ranges are not yet supported")),
Kind::Literal(_) => Err(resolver_error("Literals are not yet supported")),
}
}
2 changes: 1 addition & 1 deletion core/src/iam/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,7 @@ mod tests {
// Test with generic user identifier
//
{
let resource_id = "user:2k9qnabxuxh8k4d5gfto".to_string();
let resource_id = "user:2k9qnabxuxh8k4d5gfto".to_string();
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
Expand Down
2 changes: 1 addition & 1 deletion core/src/idx/planner/rewriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'a> KnnConditionRewriter<'a> {

fn eval_id(&self, id: &Id) -> Option<Id> {
match id {
Id::Number(_) | Id::String(_) | Id::Generate(_) => Some(id.clone()),
Id::Number(_) | Id::String(_) | Id::Generate(_) | Id::Uuid(_) => Some(id.clone()),
Id::Array(a) => self.eval_array(a).map(Id::Array),
Id::Object(o) => self.eval_object(o).map(Id::Object),
Id::Range(r) => self.eval_id_range(r).map(|v| Id::Range(Box::new(v))),
Expand Down
4 changes: 2 additions & 2 deletions core/src/key/thing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ mod tests {
let id1 = thing.id;
let val = Thing::new("testns", "testdb", "testtb", id1);
let enc = Thing::encode(&val).unwrap();
assert_eq!(enc, b"/*testns\0*testdb\0*testtb\0*\0\0\0\x02\0\0\0\x04test\0\x01");
assert_eq!(enc, b"/*testns\0*testdb\0*testtb\0*\0\0\0\x03\0\0\0\x04test\0\x01");

let dec = Thing::decode(&enc).unwrap();
assert_eq!(val, dec);
Expand All @@ -96,7 +96,7 @@ mod tests {
let id2 = thing.id;
let val = Thing::new("testns", "testdb", "testtb", id2);
let enc = Thing::encode(&val).unwrap();
assert_eq!(enc, b"/*testns\0*testdb\0*testtb\0*\0\0\0\x02\0\0\0\x07\0\0\0\0\0\0\0\x10\xf8\xe2\x38\xf2\xe7\x34\x47\xb8\x9a\x16\x47\x6b\x29\x1b\xd7\x8a\x01");
assert_eq!(enc, b"/*testns\0*testdb\0*testtb\0*\0\0\0\x03\0\0\0\x07\0\0\0\0\0\0\0\x10\xf8\xe2\x38\xf2\xe7\x34\x47\xb8\x9a\x16\x47\x6b\x29\x1b\xd7\x8a\x01");

let dec = Thing::decode(&enc).unwrap();
assert_eq!(val, dec);
Expand Down
27 changes: 20 additions & 7 deletions core/src/rpc/format/cbor/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,7 @@ impl TryFrom<Cbor> for Value {
_ => Err("Expected a CBOR text data type"),
},
// A byte string uuid
TAG_SPEC_UUID => match *v {
Data::Bytes(v) if v.len() == 16 => match v.as_slice().try_into() {
Ok(v) => Ok(Value::Uuid(Uuid::from(uuid::Uuid::from_bytes(v)))),
Err(_) => Err("Expected a CBOR byte array with 16 elements"),
},
_ => Err("Expected a CBOR byte array with 16 elements"),
},
TAG_SPEC_UUID => v.deref().to_owned().try_into().map(Value::Uuid),
// A literal decimal
TAG_STRING_DECIMAL => match *v {
Data::Text(v) => match Decimal::from_str(v.as_str()) {
Expand Down Expand Up @@ -393,6 +387,7 @@ impl TryFrom<Value> for Cbor {
match v.id {
Id::Number(v) => Data::Integer(v.into()),
Id::String(v) => Data::Text(v),
Id::Uuid(v) => Cbor::try_from(Value::from(v))?.0,
Id::Array(v) => Cbor::try_from(Value::from(v))?.0,
Id::Object(v) => Cbor::try_from(Value::from(v))?.0,
Id::Generate(_) => {
Expand Down Expand Up @@ -564,6 +559,8 @@ impl TryFrom<Data> for Id {
Data::Array(v) => Ok(Id::Array(v.try_into()?)),
Data::Map(v) => Ok(Id::Object(v.try_into()?)),
Data::Tag(TAG_RANGE, v) => Ok(Id::Range(Box::new(IdRange::try_from(*v)?))),
Data::Tag(TAG_STRING_UUID, v) => v.deref().to_owned().try_into().map(Id::Uuid),
Data::Tag(TAG_SPEC_UUID, v) => v.deref().to_owned().try_into().map(Id::Uuid),
_ => Err("Expected a CBOR integer, text, array or map"),
}
}
Expand All @@ -578,6 +575,9 @@ impl TryFrom<Id> for Data {
Id::Array(v) => Ok(Cbor::try_from(Value::from(v))?.0),
Id::Object(v) => Ok(Cbor::try_from(Value::from(v))?.0),
Id::Range(v) => Ok(Data::Tag(TAG_RANGE, Box::new(v.deref().to_owned().try_into()?))),
Id::Uuid(v) => {
Ok(Data::Tag(TAG_SPEC_UUID, Box::new(Data::Bytes(v.into_bytes().into()))))
}
Id::Generate(_) => Err("Cannot encode an ungenerated Record ID into CBOR"),
}
}
Expand All @@ -604,3 +604,16 @@ impl TryFrom<Vec<(Data, Data)>> for Object {
))
}
}

impl TryFrom<Data> for Uuid {
type Error = &'static str;
fn try_from(val: Data) -> Result<Self, &'static str> {
match val {
Data::Bytes(v) if v.len() == 16 => match v.as_slice().try_into() {
Ok(v) => Ok(Uuid::from(uuid::Uuid::from_bytes(v))),
Err(_) => Err("Expected a CBOR byte array with 16 elements"),
},
_ => Err("Expected a CBOR byte array with 16 elements"),
}
}
}
28 changes: 25 additions & 3 deletions core/src/sql/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn escape_key(s: &str) -> Cow<'_, str> {
#[inline]
/// Escapes an id if necessary
pub fn escape_rid(s: &str) -> Cow<'_, str> {
escape_numeric(s, BRACKETL, BRACKETR, BRACKET_ESC)
escape_full_numeric(s, BRACKETL, BRACKETR, BRACKET_ESC)
}

#[inline]
Expand All @@ -74,7 +74,7 @@ pub fn escape_ident(s: &str) -> Cow<'_, str> {
if let Some(x) = escape_reserved_keyword(s) {
return Cow::Owned(x);
}
escape_numeric(s, BACKTICK, BACKTICK, BACKTICK_ESC)
escape_starts_numeric(s, BACKTICK, BACKTICK, BACKTICK_ESC)
}

#[inline]
Expand All @@ -95,7 +95,29 @@ pub fn escape_reserved_keyword(s: &str) -> Option<String> {
}

#[inline]
pub fn escape_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
pub fn escape_full_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
let mut numeric = true;
// Loop over each character
for x in s.bytes() {
// Check if character is allowed
if !(x.is_ascii_alphanumeric() || x == b'_') {
return Cow::Owned(format!("{l}{}{r}", s.replace(r, e)));
}
// For every character, we need to check if it is a digit until we encounter a non-digit
if numeric && !x.is_ascii_digit() {
numeric = false;
}
}

// If all characters are digits, then we need to escape the string
if numeric {
return Cow::Owned(format!("{l}{}{r}", s.replace(r, e)));
}
Cow::Borrowed(s)
}

#[inline]
pub fn escape_starts_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
// Loop over each character
for (idx, x) in s.bytes().enumerate() {
// the first character is not allowed to be a digit.
Expand Down
8 changes: 6 additions & 2 deletions core/src/sql/id/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum Gen {
pub enum Id {
Number(i64),
String(String),
Uuid(Uuid),
Array(Array),
Object(Object),
Generate(Gen),
Expand Down Expand Up @@ -79,7 +80,7 @@ impl From<Object> for Id {

impl From<Uuid> for Id {
fn from(v: Uuid) -> Self {
Self::String(v.to_raw())
Self::Uuid(v)
}
}

Expand Down Expand Up @@ -188,13 +189,14 @@ impl Id {
}
/// Generate a new random UUID
pub fn uuid() -> Self {
Self::String(Uuid::new_v7().to_raw())
Self::Uuid(Uuid::new_v7())
}
/// Convert the Id to a raw String
pub fn to_raw(&self) -> String {
match self {
Self::Number(v) => v.to_string(),
Self::String(v) => v.to_string(),
Self::Uuid(v) => v.to_string(),
Self::Array(v) => v.to_string(),
Self::Object(v) => v.to_string(),
Self::Generate(v) => match v {
Expand All @@ -212,6 +214,7 @@ impl Display for Id {
match self {
Self::Number(v) => Display::fmt(v, f),
Self::String(v) => Display::fmt(&escape_rid(v), f),
Self::Uuid(v) => Display::fmt(v, f),
Self::Array(v) => Display::fmt(v, f),
Self::Object(v) => Display::fmt(v, f),
Self::Generate(v) => match v {
Expand All @@ -236,6 +239,7 @@ impl Id {
match self {
Id::Number(v) => Ok(Id::Number(*v)),
Id::String(v) => Ok(Id::String(v.clone())),
Id::Uuid(v) => Ok(Id::Uuid(*v)),
Id::Array(v) => match v.compute(stk, ctx, opt, doc).await? {
Value::Array(v) => Ok(Id::Array(v)),
_ => unreachable!(),
Expand Down
4 changes: 3 additions & 1 deletion core/src/sql/uuid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use super::Datetime;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Uuid";

#[revisioned(revision = 1)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[derive(
Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash,
)]
#[serde(rename = "$surrealdb::private::sql::Uuid")]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[non_exhaustive]
Expand Down
1 change: 1 addition & 0 deletions core/src/sql/value/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ impl From<Id> for Value {
match v {
Id::Number(v) => v.into(),
Id::String(v) => v.into(),
Id::Uuid(v) => v.into(),
Id::Array(v) => v.into(),
Id::Object(v) => v.into(),
Id::Generate(v) => match v {
Expand Down
6 changes: 5 additions & 1 deletion core/src/syn/parser/thing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ impl Parser<'_> {

fn kind_cast_start_id(kind: TokenKind) -> bool {
Self::tokenkind_can_start_ident(kind)
|| matches!(kind, TokenKind::Digits | t!("{") | t!("[") | t!("+") | t!("-"))
|| matches!(
kind,
TokenKind::Digits | t!("{") | t!("[") | t!("+") | t!("-") | t!("u'") | t!("u\"")
)
}

pub async fn parse_thing_or_range(
Expand Down Expand Up @@ -187,6 +190,7 @@ impl Parser<'_> {
pub async fn parse_id(&mut self, stk: &mut Stk) -> ParseResult<Id> {
let token = self.peek_whitespace();
match token.kind {
t!("u'") | t!("u\"") => Ok(Id::Uuid(self.next_token_value()?)),
t!("{") => {
self.pop_peek();
// object record id
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/tests/create.rs → sdk/tests/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ async fn create_with_id() -> Result<(), Error> {
let val = Value::parse(
"[
{
id: city:8e60244d-95f6-4f95-9e30-09a98977efb0,
id: city:u'8e60244d-95f6-4f95-9e30-09a98977efb0',
name: 'London'
}
]",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
This folder contains integration tests for the `surreal` CLI binary.

See [`lib/tests`](../lib/tests/) for `surrealdb` library integration tests.
See [`sdk/tests`](../sdk/tests/) for `surrealdb` library integration tests.

To read server log output from these tests, you need to find the file containing the output.
You can find this file by setting `RUST_LOG=debug`.
2 changes: 1 addition & 1 deletion tests/sdk/local/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "1.0.0"
edition = "2021"

[dependencies]
surrealdb = { path = "../../../lib", features = ["kv-mem"] }
surrealdb = { path = "../../../sdk", features = ["kv-mem"] }
tokio = { version = "1", features = ["full"] }

[workspace]
Expand Down
2 changes: 1 addition & 1 deletion tests/sdk/remote/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "1.0.0"
edition = "2021"

[dependencies]
surrealdb = { path = "../../../lib" }
surrealdb = { path = "../../../sdk" }
tokio = { version = "1", features = ["full"] }

[workspace]
Expand Down

0 comments on commit 50e53f6

Please sign in to comment.