Implement SQL Array as a newtype tuple struct
This commit is contained in:
parent
3ee1ddb5b1
commit
143da56728
20 changed files with 166 additions and 193 deletions
|
@ -45,7 +45,7 @@ impl Array {
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
chn: &Sender<(Option<Thing>, Value)>,
|
chn: &Sender<(Option<Thing>, Value)>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
for v in self.value.into_iter() {
|
for v in self {
|
||||||
if ctx.is_ok() {
|
if ctx.is_ok() {
|
||||||
match v {
|
match v {
|
||||||
Value::Array(v) => v.process(ctx, opt, stm, txn, chn).await?,
|
Value::Array(v) => v.process(ctx, opt, stm, txn, chn).await?,
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl Array {
|
||||||
txn: &Transaction,
|
txn: &Transaction,
|
||||||
ite: &mut Iterator,
|
ite: &mut Iterator,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
for v in self.value.into_iter() {
|
for v in self.into_iter() {
|
||||||
if ctx.is_ok() {
|
if ctx.is_ok() {
|
||||||
match v {
|
match v {
|
||||||
Value::Array(v) => v.iterate(ctx, opt, txn, ite).await?,
|
Value::Array(v) => v.iterate(ctx, opt, txn, ite).await?,
|
||||||
|
|
|
@ -169,7 +169,7 @@ impl Iterator {
|
||||||
// Set the value at the path
|
// Set the value at the path
|
||||||
match val {
|
match val {
|
||||||
Value::Array(v) => {
|
Value::Array(v) => {
|
||||||
for val in v.value {
|
for val in v {
|
||||||
// Make a copy of object
|
// Make a copy of object
|
||||||
let mut obj = obj.clone();
|
let mut obj = obj.clone();
|
||||||
// Set the value at the path
|
// Set the value at the path
|
||||||
|
@ -215,11 +215,11 @@ impl Iterator {
|
||||||
// Get the value at the path
|
// Get the value at the path
|
||||||
let val = obj.pick(&group.group);
|
let val = obj.pick(&group.group);
|
||||||
// Set the value at the path
|
// Set the value at the path
|
||||||
arr.value.push(val);
|
arr.push(val);
|
||||||
}
|
}
|
||||||
// Add to grouped collection
|
// Add to grouped collection
|
||||||
match grp.get_mut(&arr) {
|
match grp.get_mut(&arr) {
|
||||||
Some(v) => v.value.push(obj),
|
Some(v) => v.push(obj),
|
||||||
None => {
|
None => {
|
||||||
grp.insert(arr, Array::from(obj));
|
grp.insert(arr, Array::from(obj));
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,13 @@ impl<'a> Document<'a> {
|
||||||
let mut o = Array::with_capacity(ix.cols.len());
|
let mut o = Array::with_capacity(ix.cols.len());
|
||||||
for i in ix.cols.iter() {
|
for i in ix.cols.iter() {
|
||||||
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
|
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
|
||||||
o.value.push(v);
|
o.push(v);
|
||||||
}
|
}
|
||||||
// Calculate new values
|
// Calculate new values
|
||||||
let mut n = Array::with_capacity(ix.cols.len());
|
let mut n = Array::with_capacity(ix.cols.len());
|
||||||
for i in ix.cols.iter() {
|
for i in ix.cols.iter() {
|
||||||
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
|
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
|
||||||
n.value.push(v);
|
n.push(v);
|
||||||
}
|
}
|
||||||
// Clone transaction
|
// Clone transaction
|
||||||
let run = txn.clone();
|
let run = txn.clone();
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::sql::value::Value;
|
||||||
pub fn concat(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn concat(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => match args.remove(0) {
|
Value::Array(v) => match args.remove(0) {
|
||||||
Value::Array(w) => Ok(v.value.concat(w.value).into()),
|
Value::Array(w) => Ok(v.concat(w).into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
|
@ -21,7 +21,7 @@ pub fn concat(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
pub fn combine(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn combine(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => match args.remove(0) {
|
Value::Array(v) => match args.remove(0) {
|
||||||
Value::Array(w) => Ok(v.value.combine(w.value).into()),
|
Value::Array(w) => Ok(v.combine(w).into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
|
@ -31,7 +31,7 @@ pub fn combine(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
pub fn difference(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn difference(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => match args.remove(0) {
|
Value::Array(v) => match args.remove(0) {
|
||||||
Value::Array(w) => Ok(v.value.difference(w.value).into()),
|
Value::Array(w) => Ok(v.difference(w).into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
|
@ -40,7 +40,7 @@ pub fn difference(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
|
|
||||||
pub fn distinct(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn distinct(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => Ok(v.value.uniq().into()),
|
Value::Array(v) => Ok(v.uniq().into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ pub fn distinct(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
pub fn intersect(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn intersect(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => match args.remove(0) {
|
Value::Array(v) => match args.remove(0) {
|
||||||
Value::Array(w) => Ok(v.value.intersect(w.value).into()),
|
Value::Array(w) => Ok(v.intersect(w).into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
|
@ -57,7 +57,7 @@ pub fn intersect(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
|
|
||||||
pub fn len(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn len(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => Ok(v.value.len().into()),
|
Value::Array(v) => Ok(v.len().into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ pub fn len(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
pub fn union(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn union(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.remove(0) {
|
match args.remove(0) {
|
||||||
Value::Array(v) => match args.remove(0) {
|
Value::Array(v) => match args.remove(0) {
|
||||||
Value::Array(w) => Ok(v.value.union(w.value).into()),
|
Value::Array(w) => Ok(v.union(w).into()),
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
},
|
},
|
||||||
_ => Ok(Value::None),
|
_ => Ok(Value::None),
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::sql::value::Value;
|
||||||
pub fn count(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
pub fn count(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.len() {
|
match args.len() {
|
||||||
1 => match args.remove(0) {
|
1 => match args.remove(0) {
|
||||||
Value::Array(v) => Ok(v.value.iter().filter(|v| v.is_truthy()).count().into()),
|
Value::Array(v) => Ok(v.iter().filter(|v| v.is_truthy()).count().into()),
|
||||||
v => match v.is_truthy() {
|
v => match v.is_truthy() {
|
||||||
true => Ok(1.into()),
|
true => Ok(1.into()),
|
||||||
false => Ok(0.into()),
|
false => Ok(0.into()),
|
||||||
|
|
|
@ -20,11 +20,11 @@ pub fn r#enum(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||||
match args.len() {
|
match args.len() {
|
||||||
0 => Ok(Value::None),
|
0 => Ok(Value::None),
|
||||||
1 => match args.remove(0) {
|
1 => match args.remove(0) {
|
||||||
Value::Array(mut v) => match v.value.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
0 => Ok(Value::None),
|
0 => Ok(Value::None),
|
||||||
n => {
|
n => {
|
||||||
let i = rand::thread_rng().gen_range(0..n);
|
let i = rand::thread_rng().gen_range(0..n);
|
||||||
Ok(v.value.remove(i))
|
Ok(v.remove(i))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
|
|
@ -12,120 +12,113 @@ use crate::sql::value::{value, Value};
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
use nom::combinator::opt;
|
use nom::combinator::opt;
|
||||||
use nom::multi::separated_list0;
|
use nom::multi::separated_list0;
|
||||||
use serde::ser::SerializeStruct;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)]
|
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)]
|
||||||
pub struct Array {
|
pub struct Array(pub Vec<Value>);
|
||||||
pub value: Vec<Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Value> for Array {
|
impl From<Value> for Array {
|
||||||
fn from(v: Value) -> Self {
|
fn from(v: Value) -> Self {
|
||||||
Array {
|
Array(vec![v])
|
||||||
value: vec![v],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Value>> for Array {
|
impl From<Vec<Value>> for Array {
|
||||||
fn from(v: Vec<Value>) -> Self {
|
fn from(v: Vec<Value>) -> Self {
|
||||||
Array {
|
Array(v)
|
||||||
value: v,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<i32>> for Array {
|
impl From<Vec<i32>> for Array {
|
||||||
fn from(v: Vec<i32>) -> Self {
|
fn from(v: Vec<i32>) -> Self {
|
||||||
Array {
|
Array(v.into_iter().map(|x| x.into()).collect())
|
||||||
value: v.into_iter().map(|x| x.into()).collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<String>> for Array {
|
impl From<Vec<String>> for Array {
|
||||||
fn from(v: Vec<String>) -> Self {
|
fn from(v: Vec<String>) -> Self {
|
||||||
Array {
|
Array(v.into_iter().map(|x| x.into()).collect())
|
||||||
value: v.into_iter().map(|x| x.into()).collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Vec<Value>>> for Array {
|
impl From<Vec<Vec<Value>>> for Array {
|
||||||
fn from(v: Vec<Vec<Value>>) -> Self {
|
fn from(v: Vec<Vec<Value>>) -> Self {
|
||||||
Array {
|
Array(v.into_iter().map(|x| x.into()).collect())
|
||||||
value: v.into_iter().map(|x| x.into()).collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<Vec<&str>> for Array {
|
impl<'a> From<Vec<&str>> for Array {
|
||||||
fn from(v: Vec<&str>) -> Self {
|
fn from(v: Vec<&str>) -> Self {
|
||||||
Array {
|
Array(v.into_iter().map(Value::from).collect())
|
||||||
value: v.into_iter().map(Value::from).collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Operation>> for Array {
|
impl From<Vec<Operation>> for Array {
|
||||||
fn from(v: Vec<Operation>) -> Self {
|
fn from(v: Vec<Operation>) -> Self {
|
||||||
Array {
|
Array(v.into_iter().map(Value::from).collect())
|
||||||
value: v.into_iter().map(Value::from).collect(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for Array {
|
||||||
|
type Target = Vec<Value>;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Array {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for Array {
|
||||||
|
type Item = Value;
|
||||||
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.0.into_iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Array {
|
impl Array {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Array {
|
Array(Vec::default())
|
||||||
value: Vec::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_capacity(len: usize) -> Self {
|
pub fn with_capacity(len: usize) -> Self {
|
||||||
Array {
|
Array(Vec::with_capacity(len))
|
||||||
value: Vec::with_capacity(len),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.value.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.value.is_empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_ints(self) -> Vec<i64> {
|
pub fn as_ints(self) -> Vec<i64> {
|
||||||
self.value.into_iter().map(|v| v.as_int()).collect()
|
self.0.into_iter().map(|v| v.as_int()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_floats(self) -> Vec<f64> {
|
pub fn as_floats(self) -> Vec<f64> {
|
||||||
self.value.into_iter().map(|v| v.as_float()).collect()
|
self.0.into_iter().map(|v| v.as_float()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_numbers(self) -> Vec<Number> {
|
pub fn as_numbers(self) -> Vec<Number> {
|
||||||
self.value.into_iter().map(|v| v.as_number()).collect()
|
self.0.into_iter().map(|v| v.as_number()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_strands(self) -> Vec<Strand> {
|
pub fn as_strands(self) -> Vec<Strand> {
|
||||||
self.value.into_iter().map(|v| v.as_strand()).collect()
|
self.0.into_iter().map(|v| v.as_strand()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_point(mut self) -> [f64; 2] {
|
pub fn as_point(mut self) -> [f64; 2] {
|
||||||
match self.len() {
|
match self.len() {
|
||||||
0 => [0.0, 0.0],
|
0 => [0.0, 0.0],
|
||||||
1 => [self.value.remove(0).as_float(), 0.0],
|
1 => [self.0.remove(0).as_float(), 0.0],
|
||||||
_ => [self.value.remove(0).as_float(), self.value.remove(0).as_float()],
|
_ => [self.0.remove(0).as_float(), self.0.remove(0).as_float()],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_operations(&self) -> Result<Vec<Operation>, Error> {
|
pub fn to_operations(&self) -> Result<Vec<Operation>, Error> {
|
||||||
self.value
|
self.iter()
|
||||||
.iter()
|
|
||||||
.map(|v| match v {
|
.map(|v| match v {
|
||||||
Value::Object(v) => v.to_operation(),
|
Value::Object(v) => v.to_operation(),
|
||||||
_ => Err(Error::InvalidPatch {
|
_ => Err(Error::InvalidPatch {
|
||||||
|
@ -145,25 +138,19 @@ impl Array {
|
||||||
doc: Option<&Value>,
|
doc: Option<&Value>,
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
let mut x = Vec::new();
|
let mut x = Vec::new();
|
||||||
for v in &self.value {
|
for v in self.iter() {
|
||||||
match v.compute(ctx, opt, txn, doc).await {
|
match v.compute(ctx, opt, txn, doc).await {
|
||||||
Ok(v) => x.push(v),
|
Ok(v) => x.push(v),
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(Value::Array(Array {
|
Ok(Value::Array(Array(x)))
|
||||||
value: x,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Array {
|
impl fmt::Display for Array {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "[{}]", self.iter().map(|ref v| format!("{}", v)).collect::<Vec<_>>().join(", "))
|
||||||
f,
|
|
||||||
"[{}]",
|
|
||||||
self.value.iter().map(|ref v| format!("{}", v)).collect::<Vec<_>>().join(", ")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,11 +160,9 @@ impl Serialize for Array {
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
if serializer.is_human_readable() {
|
if serializer.is_human_readable() {
|
||||||
serializer.serialize_some(&self.value)
|
serializer.serialize_some(&self.0)
|
||||||
} else {
|
} else {
|
||||||
let mut val = serializer.serialize_struct("Array", 1)?;
|
serializer.serialize_newtype_struct("Array", &self.0)
|
||||||
val.serialize_field("value", &self.value)?;
|
|
||||||
val.end()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,8 +172,8 @@ impl Serialize for Array {
|
||||||
impl ops::Add<Value> for Array {
|
impl ops::Add<Value> for Array {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(mut self, other: Value) -> Self {
|
fn add(mut self, other: Value) -> Self {
|
||||||
if !self.value.iter().any(|x| *x == other) {
|
if !self.0.iter().any(|x| *x == other) {
|
||||||
self.value.push(other)
|
self.0.push(other)
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -197,9 +182,9 @@ impl ops::Add<Value> for Array {
|
||||||
impl ops::Add for Array {
|
impl ops::Add for Array {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(mut self, other: Self) -> Self {
|
fn add(mut self, other: Self) -> Self {
|
||||||
for v in other.value {
|
for v in other.0 {
|
||||||
if !self.value.iter().any(|x| *x == v) {
|
if !self.0.iter().any(|x| *x == v) {
|
||||||
self.value.push(v)
|
self.0.push(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
@ -211,8 +196,8 @@ impl ops::Add for Array {
|
||||||
impl ops::Sub<Value> for Array {
|
impl ops::Sub<Value> for Array {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn sub(mut self, other: Value) -> Self {
|
fn sub(mut self, other: Value) -> Self {
|
||||||
if let Some(p) = self.value.iter().position(|x| *x == other) {
|
if let Some(p) = self.0.iter().position(|x| *x == other) {
|
||||||
self.value.remove(p);
|
self.0.remove(p);
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -221,9 +206,9 @@ impl ops::Sub<Value> for Array {
|
||||||
impl ops::Sub for Array {
|
impl ops::Sub for Array {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn sub(mut self, other: Self) -> Self {
|
fn sub(mut self, other: Self) -> Self {
|
||||||
for v in other.value {
|
for v in other.0 {
|
||||||
if let Some(p) = self.value.iter().position(|x| *x == v) {
|
if let Some(p) = self.0.iter().position(|x| *x == v) {
|
||||||
self.value.remove(p);
|
self.0.remove(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
|
@ -265,15 +250,15 @@ impl<T> Abolish<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Combine<T> {
|
pub trait Combine<T> {
|
||||||
fn combine(self, other: Vec<T>) -> Vec<Vec<T>>;
|
fn combine(self, other: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + Clone> Combine<T> for Vec<T> {
|
impl Combine<Array> for Array {
|
||||||
fn combine(self, other: Vec<T>) -> Vec<Vec<T>> {
|
fn combine(self, other: Array) -> Array {
|
||||||
let mut out = Vec::new();
|
let mut out = Array::new();
|
||||||
for a in self.iter() {
|
for a in self.iter() {
|
||||||
for b in other.iter() {
|
for b in other.iter() {
|
||||||
out.push(vec![a.clone(), b.clone()]);
|
out.push(vec![a.clone(), b.clone()].into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
@ -283,11 +268,11 @@ impl<T: PartialEq + Clone> Combine<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Concat<T> {
|
pub trait Concat<T> {
|
||||||
fn concat(self, other: Vec<T>) -> Vec<T>;
|
fn concat(self, other: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> Concat<T> for Vec<T> {
|
impl Concat<Array> for Array {
|
||||||
fn concat(mut self, mut other: Vec<T>) -> Vec<T> {
|
fn concat(mut self, mut other: Array) -> Array {
|
||||||
self.append(&mut other);
|
self.append(&mut other);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -296,12 +281,12 @@ impl<T: PartialEq> Concat<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Difference<T> {
|
pub trait Difference<T> {
|
||||||
fn difference(self, other: Vec<T>) -> Vec<T>;
|
fn difference(self, other: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> Difference<T> for Vec<T> {
|
impl Difference<Array> for Array {
|
||||||
fn difference(self, other: Vec<T>) -> Vec<T> {
|
fn difference(self, other: Array) -> Array {
|
||||||
let mut out = Vec::new();
|
let mut out = Array::new();
|
||||||
let mut other: Vec<_> = other.into_iter().collect();
|
let mut other: Vec<_> = other.into_iter().collect();
|
||||||
for a in self.into_iter() {
|
for a in self.into_iter() {
|
||||||
if let Some(pos) = other.iter().position(|b| a == *b) {
|
if let Some(pos) = other.iter().position(|b| a == *b) {
|
||||||
|
@ -318,14 +303,14 @@ impl<T: PartialEq> Difference<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Intersect<T> {
|
pub trait Intersect<T> {
|
||||||
fn intersect(self, other: Vec<T>) -> Vec<T>;
|
fn intersect(self, other: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> Intersect<T> for Vec<T> {
|
impl Intersect<Array> for Array {
|
||||||
fn intersect(self, other: Vec<T>) -> Vec<T> {
|
fn intersect(self, other: Array) -> Array {
|
||||||
let mut out = Vec::new();
|
let mut out = Array::new();
|
||||||
let mut other: Vec<_> = other.into_iter().collect();
|
let mut other: Vec<_> = other.into_iter().collect();
|
||||||
for a in self.into_iter() {
|
for a in self.0.into_iter() {
|
||||||
if let Some(pos) = other.iter().position(|b| a == *b) {
|
if let Some(pos) = other.iter().position(|b| a == *b) {
|
||||||
out.push(a);
|
out.push(a);
|
||||||
other.remove(pos);
|
other.remove(pos);
|
||||||
|
@ -338,11 +323,11 @@ impl<T: PartialEq> Intersect<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Union<T> {
|
pub trait Union<T> {
|
||||||
fn union(self, other: Vec<T>) -> Vec<T>;
|
fn union(self, other: T) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> Union<T> for Vec<T> {
|
impl Union<Array> for Array {
|
||||||
fn union(mut self, mut other: Vec<T>) -> Vec<T> {
|
fn union(mut self, mut other: Array) -> Array {
|
||||||
self.append(&mut other);
|
self.append(&mut other);
|
||||||
self.uniq()
|
self.uniq()
|
||||||
}
|
}
|
||||||
|
@ -351,11 +336,11 @@ impl<T: PartialEq> Union<T> for Vec<T> {
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
pub trait Uniq<T> {
|
pub trait Uniq<T> {
|
||||||
fn uniq(self) -> Vec<T>;
|
fn uniq(self) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> Uniq<T> for Vec<T> {
|
impl Uniq<Array> for Array {
|
||||||
fn uniq(mut self) -> Vec<T> {
|
fn uniq(mut self) -> Array {
|
||||||
for x in (0..self.len()).rev() {
|
for x in (0..self.len()).rev() {
|
||||||
for y in (x + 1..self.len()).rev() {
|
for y in (x + 1..self.len()).rev() {
|
||||||
if self[x] == self[y] {
|
if self[x] == self[y] {
|
||||||
|
@ -377,12 +362,7 @@ pub fn array(i: &str) -> IResult<&str, Array> {
|
||||||
let (i, _) = opt(char(','))(i)?;
|
let (i, _) = opt(char(','))(i)?;
|
||||||
let (i, _) = mightbespace(i)?;
|
let (i, _) = mightbespace(i)?;
|
||||||
let (i, _) = char(']')(i)?;
|
let (i, _) = char(']')(i)?;
|
||||||
Ok((
|
Ok((i, Array(v)))
|
||||||
i,
|
|
||||||
Array {
|
|
||||||
value: v,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item(i: &str) -> IResult<&str, Value> {
|
fn item(i: &str) -> IResult<&str, Value> {
|
||||||
|
@ -402,7 +382,7 @@ mod tests {
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let out = res.unwrap().1;
|
let out = res.unwrap().1;
|
||||||
assert_eq!("[1, 2, 3]", format!("{}", out));
|
assert_eq!("[1, 2, 3]", format!("{}", out));
|
||||||
assert_eq!(out.value.len(), 3);
|
assert_eq!(out.0.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -412,7 +392,7 @@ mod tests {
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let out = res.unwrap().1;
|
let out = res.unwrap().1;
|
||||||
assert_eq!("[1, 2, 3]", format!("{}", out));
|
assert_eq!("[1, 2, 3]", format!("{}", out));
|
||||||
assert_eq!(out.value.len(), 3);
|
assert_eq!(out.0.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -422,6 +402,6 @@ mod tests {
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let out = res.unwrap().1;
|
let out = res.unwrap().1;
|
||||||
assert_eq!("[1, 2, 3 + 1]", format!("{}", out));
|
assert_eq!("[1, 2, 3 + 1]", format!("{}", out));
|
||||||
assert_eq!(out.value.len(), 3);
|
assert_eq!(out.0.len(), 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl InsertStatement {
|
||||||
Data::SingleExpression(v) => {
|
Data::SingleExpression(v) => {
|
||||||
let v = v.compute(ctx, opt, txn, doc).await?;
|
let v = v.compute(ctx, opt, txn, doc).await?;
|
||||||
match v {
|
match v {
|
||||||
Value::Array(v) => v.value.into_iter().for_each(|v| i.prepare(v)),
|
Value::Array(v) => v.into_iter().for_each(|v| i.prepare(v)),
|
||||||
Value::Object(_) => i.prepare(v),
|
Value::Object(_) => i.prepare(v),
|
||||||
v => {
|
v => {
|
||||||
return Err(Error::InsertStatement {
|
return Err(Error::InsertStatement {
|
||||||
|
|
|
@ -91,7 +91,7 @@ impl Subquery {
|
||||||
// Process subquery
|
// Process subquery
|
||||||
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
||||||
Value::Array(mut v) => match v.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
1 => Ok(v.value.remove(0)),
|
1 => Ok(v.remove(0)),
|
||||||
_ => Ok(v.into()),
|
_ => Ok(v.into()),
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
@ -112,7 +112,7 @@ impl Subquery {
|
||||||
// Process subquery
|
// Process subquery
|
||||||
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
||||||
Value::Array(mut v) => match v.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
1 => Ok(v.value.remove(0)),
|
1 => Ok(v.remove(0)),
|
||||||
_ => Ok(v.into()),
|
_ => Ok(v.into()),
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
@ -133,7 +133,7 @@ impl Subquery {
|
||||||
// Process subquery
|
// Process subquery
|
||||||
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
||||||
Value::Array(mut v) => match v.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
1 => Ok(v.value.remove(0)),
|
1 => Ok(v.remove(0)),
|
||||||
_ => Ok(v.into()),
|
_ => Ok(v.into()),
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
@ -154,7 +154,7 @@ impl Subquery {
|
||||||
// Process subquery
|
// Process subquery
|
||||||
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
||||||
Value::Array(mut v) => match v.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
1 => Ok(v.value.remove(0)),
|
1 => Ok(v.remove(0)),
|
||||||
_ => Ok(v.into()),
|
_ => Ok(v.into()),
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
@ -175,7 +175,7 @@ impl Subquery {
|
||||||
// Process subquery
|
// Process subquery
|
||||||
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
|
||||||
Value::Array(mut v) => match v.len() {
|
Value::Array(mut v) => match v.len() {
|
||||||
1 => Ok(v.value.remove(0)),
|
1 => Ok(v.remove(0)),
|
||||||
_ => Ok(v.into()),
|
_ => Ok(v.into()),
|
||||||
},
|
},
|
||||||
v => Ok(v),
|
v => Ok(v),
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Value {
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
(Value::Array(a), Value::Array(b)) => match p {
|
(Value::Array(a), Value::Array(b)) => match p {
|
||||||
Part::All => {
|
Part::All => {
|
||||||
for (a, b) in a.value.iter().zip(b.value.iter()) {
|
for (a, b) in a.iter().zip(b.iter()) {
|
||||||
match a.compare(b, path.next(), collate, numeric) {
|
match a.compare(b, path.next(), collate, numeric) {
|
||||||
Some(Ordering::Equal) => continue,
|
Some(Ordering::Equal) => continue,
|
||||||
None => continue,
|
None => continue,
|
||||||
|
@ -40,28 +40,26 @@ impl Value {
|
||||||
_ => Some(Ordering::Equal),
|
_ => Some(Ordering::Equal),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Part::First => match (a.value.first(), b.value.first()) {
|
Part::First => match (a.first(), b.first()) {
|
||||||
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
||||||
(Some(_), None) => Some(Ordering::Greater),
|
(Some(_), None) => Some(Ordering::Greater),
|
||||||
(None, Some(_)) => Some(Ordering::Less),
|
(None, Some(_)) => Some(Ordering::Less),
|
||||||
(_, _) => Some(Ordering::Equal),
|
(_, _) => Some(Ordering::Equal),
|
||||||
},
|
},
|
||||||
Part::Last => match (a.value.first(), b.value.first()) {
|
Part::Last => match (a.first(), b.first()) {
|
||||||
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
||||||
(Some(_), None) => Some(Ordering::Greater),
|
(Some(_), None) => Some(Ordering::Greater),
|
||||||
(None, Some(_)) => Some(Ordering::Less),
|
(None, Some(_)) => Some(Ordering::Less),
|
||||||
(_, _) => Some(Ordering::Equal),
|
(_, _) => Some(Ordering::Equal),
|
||||||
},
|
},
|
||||||
Part::Index(i) => {
|
Part::Index(i) => match (a.get(i.to_usize()), b.get(i.to_usize())) {
|
||||||
match (a.value.get(i.to_usize()), b.value.get(i.to_usize())) {
|
|
||||||
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
|
||||||
(Some(_), None) => Some(Ordering::Greater),
|
(Some(_), None) => Some(Ordering::Greater),
|
||||||
(None, Some(_)) => Some(Ordering::Less),
|
(None, Some(_)) => Some(Ordering::Less),
|
||||||
(_, _) => Some(Ordering::Equal),
|
(_, _) => Some(Ordering::Equal),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
for (a, b) in a.value.iter().zip(b.value.iter()) {
|
for (a, b) in a.iter().zip(b.iter()) {
|
||||||
match a.compare(b, path, collate, numeric) {
|
match a.compare(b, path, collate, numeric) {
|
||||||
Some(Ordering::Equal) => continue,
|
Some(Ordering::Equal) => continue,
|
||||||
None => continue,
|
None => continue,
|
||||||
|
|
|
@ -41,48 +41,50 @@ impl Value {
|
||||||
Value::Array(v) => match p {
|
Value::Array(v) => match p {
|
||||||
Part::All => match path.len() {
|
Part::All => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
v.value.clear();
|
v.clear();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
let futs = v.value.iter_mut().map(|v| v.del(ctx, opt, txn, path));
|
let futs = v.iter_mut().map(|v| v.del(ctx, opt, txn, path));
|
||||||
try_join_all(futs).await?;
|
try_join_all(futs).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Part::First => match path.len() {
|
Part::First => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
if v.value.len().gt(&0) {
|
if v.len().gt(&0) {
|
||||||
v.value.remove(0);
|
let i = 0;
|
||||||
|
v.remove(i);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => match v.value.first_mut() {
|
_ => match v.first_mut() {
|
||||||
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Part::Last => match path.len() {
|
Part::Last => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
if v.value.len().gt(&0) {
|
if v.len().gt(&0) {
|
||||||
v.value.remove(v.value.len() - 1);
|
let i = v.len() - 1;
|
||||||
|
v.remove(i);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => match v.value.last_mut() {
|
_ => match v.last_mut() {
|
||||||
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Part::Index(i) => match path.len() {
|
Part::Index(i) => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
if v.value.len().gt(&i.to_usize()) {
|
if v.len().gt(&i.to_usize()) {
|
||||||
v.value.remove(i.to_usize());
|
v.remove(i.to_usize());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => match v.value.get_mut(i.to_usize()) {
|
_ => match v.get_mut(i.to_usize()) {
|
||||||
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
Some(v) => v.del(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
|
@ -90,17 +92,17 @@ impl Value {
|
||||||
Part::Where(w) => match path.len() {
|
Part::Where(w) => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
for (i, v) in v.value.iter().enumerate() {
|
for (i, v) in v.iter().enumerate() {
|
||||||
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
||||||
m.insert(i, ());
|
m.insert(i, ());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
v.value.abolish(|i| m.contains_key(&i));
|
v.abolish(|i| m.contains_key(&i));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
for v in &mut v.value {
|
for v in v.iter_mut() {
|
||||||
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
||||||
v.del(ctx, opt, txn, path).await?;
|
v.del(ctx, opt, txn, path).await?;
|
||||||
}
|
}
|
||||||
|
@ -110,11 +112,11 @@ impl Value {
|
||||||
},
|
},
|
||||||
_ => match path.len() {
|
_ => match path.len() {
|
||||||
1 => {
|
1 => {
|
||||||
v.value.clear();
|
v.clear();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let futs = v.value.iter_mut().map(|v| v.del(ctx, opt, txn, path));
|
let futs = v.iter_mut().map(|v| v.del(ctx, opt, txn, path));
|
||||||
try_join_all(futs).await?;
|
try_join_all(futs).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl Value {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
while n < min(a.len(), b.len()) {
|
while n < min(a.len(), b.len()) {
|
||||||
let path = path.clone().push(n.into());
|
let path = path.clone().push(n.into());
|
||||||
ops.append(&mut a.value[n].diff(&b.value[n], path));
|
ops.append(&mut a[n].diff(&b[n], path));
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
while n < b.len() {
|
while n < b.len() {
|
||||||
|
@ -45,7 +45,7 @@ impl Value {
|
||||||
ops.push(Operation {
|
ops.push(Operation {
|
||||||
op: Op::Add,
|
op: Op::Add,
|
||||||
path: path.clone().push(n.into()),
|
path: path.clone().push(n.into()),
|
||||||
value: b.value[n].clone(),
|
value: b[n].clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
n += 1;
|
n += 1;
|
||||||
|
|
|
@ -23,25 +23,23 @@ impl Value {
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
Value::Array(v) => match p {
|
Value::Array(v) => match p {
|
||||||
Part::All => v
|
Part::All => v
|
||||||
.value
|
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))
|
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
Part::First => match v.value.first() {
|
Part::First => match v.first() {
|
||||||
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
},
|
},
|
||||||
Part::Last => match v.value.last() {
|
Part::Last => match v.last() {
|
||||||
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
},
|
},
|
||||||
Part::Index(i) => match v.value.get(i.to_usize()) {
|
Part::Index(i) => match v.get(i.to_usize()) {
|
||||||
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
Some(v) => v._each(path.next(), prev.push(p.clone())),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
},
|
},
|
||||||
_ => v
|
_ => v
|
||||||
.value
|
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))
|
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))
|
||||||
|
|
|
@ -15,7 +15,6 @@ impl Value {
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
Value::Array(v) => v
|
Value::Array(v) => v
|
||||||
.value
|
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(i, v)| v._every(prev.clone().push(Part::from(i))))
|
.flat_map(|(i, v)| v._every(prev.clone().push(Part::from(i))))
|
||||||
|
|
|
@ -37,25 +37,25 @@ impl Value {
|
||||||
Value::Array(v) => match p {
|
Value::Array(v) => match p {
|
||||||
Part::All => {
|
Part::All => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
let futs = v.value.iter().map(|v| v.get(ctx, opt, txn, path));
|
let futs = v.iter().map(|v| v.get(ctx, opt, txn, path));
|
||||||
try_join_all(futs).await.map(|v| v.into())
|
try_join_all(futs).await.map(|v| v.into())
|
||||||
}
|
}
|
||||||
Part::First => match v.value.first() {
|
Part::First => match v.first() {
|
||||||
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(Value::None),
|
None => Ok(Value::None),
|
||||||
},
|
},
|
||||||
Part::Last => match v.value.last() {
|
Part::Last => match v.last() {
|
||||||
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(Value::None),
|
None => Ok(Value::None),
|
||||||
},
|
},
|
||||||
Part::Index(i) => match v.value.get(i.to_usize()) {
|
Part::Index(i) => match v.get(i.to_usize()) {
|
||||||
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
Some(v) => v.get(ctx, opt, txn, path.next()).await,
|
||||||
None => Ok(Value::None),
|
None => Ok(Value::None),
|
||||||
},
|
},
|
||||||
Part::Where(w) => {
|
Part::Where(w) => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
let mut a = Vec::new();
|
let mut a = Vec::new();
|
||||||
for v in &v.value {
|
for v in v.iter() {
|
||||||
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
||||||
a.push(v.get(ctx, opt, txn, path).await?)
|
a.push(v.get(ctx, opt, txn, path).await?)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl Value {
|
||||||
Ok(a.into())
|
Ok(a.into())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let futs = v.value.iter().map(|v| v.get(ctx, opt, txn, path));
|
let futs = v.iter().map(|v| v.get(ctx, opt, txn, path));
|
||||||
try_join_all(futs).await.map(|v| v.into())
|
try_join_all(futs).await.map(|v| v.into())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,22 +18,20 @@ impl Value {
|
||||||
},
|
},
|
||||||
// Current path part is an array
|
// Current path part is an array
|
||||||
Value::Array(v) => match p {
|
Value::Array(v) => match p {
|
||||||
Part::All => {
|
Part::All => v.iter().map(|v| v.pick(path.next())).collect::<Vec<_>>().into(),
|
||||||
v.value.iter().map(|v| v.pick(path.next())).collect::<Vec<_>>().into()
|
Part::First => match v.first() {
|
||||||
}
|
|
||||||
Part::First => match v.value.first() {
|
|
||||||
Some(v) => v.pick(path.next()),
|
Some(v) => v.pick(path.next()),
|
||||||
None => Value::None,
|
None => Value::None,
|
||||||
},
|
},
|
||||||
Part::Last => match v.value.last() {
|
Part::Last => match v.last() {
|
||||||
Some(v) => v.pick(path.next()),
|
Some(v) => v.pick(path.next()),
|
||||||
None => Value::None,
|
None => Value::None,
|
||||||
},
|
},
|
||||||
Part::Index(i) => match v.value.get(i.to_usize()) {
|
Part::Index(i) => match v.get(i.to_usize()) {
|
||||||
Some(v) => v.pick(path.next()),
|
Some(v) => v.pick(path.next()),
|
||||||
None => Value::None,
|
None => Value::None,
|
||||||
},
|
},
|
||||||
_ => v.value.iter().map(|v| v.pick(path)).collect::<Vec<_>>().into(),
|
_ => v.iter().map(|v| v.pick(path)).collect::<Vec<_>>().into(),
|
||||||
},
|
},
|
||||||
// Ignore everything else
|
// Ignore everything else
|
||||||
_ => Value::None,
|
_ => Value::None,
|
||||||
|
|
|
@ -39,26 +39,25 @@ impl Value {
|
||||||
Value::Array(v) => match p {
|
Value::Array(v) => match p {
|
||||||
Part::All => {
|
Part::All => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
let futs =
|
let futs = v.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
|
||||||
v.value.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
|
|
||||||
try_join_all(futs).await?;
|
try_join_all(futs).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Part::First => match v.value.first_mut() {
|
Part::First => match v.first_mut() {
|
||||||
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
Part::Last => match v.value.last_mut() {
|
Part::Last => match v.last_mut() {
|
||||||
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
Part::Index(i) => match v.value.get_mut(i.to_usize()) {
|
Part::Index(i) => match v.get_mut(i.to_usize()) {
|
||||||
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
},
|
},
|
||||||
Part::Where(w) => {
|
Part::Where(w) => {
|
||||||
let path = path.next();
|
let path = path.next();
|
||||||
for v in &mut v.value {
|
for v in v.iter_mut() {
|
||||||
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
||||||
v.set(ctx, opt, txn, path, val.clone()).await?;
|
v.set(ctx, opt, txn, path, val.clone()).await?;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +65,7 @@ impl Value {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let futs =
|
let futs = v.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
|
||||||
v.value.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
|
|
||||||
try_join_all(futs).await?;
|
try_join_all(futs).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::sql::value::Value;
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn single(&self) -> &Self {
|
pub fn single(&self) -> &Self {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => match v.value.first() {
|
Value::Array(v) => match v.first() {
|
||||||
None => &Value::None,
|
None => &Value::None,
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
},
|
},
|
||||||
|
|
|
@ -498,7 +498,7 @@ impl Value {
|
||||||
Value::False => false,
|
Value::False => false,
|
||||||
Value::Thing(_) => true,
|
Value::Thing(_) => true,
|
||||||
Value::Geometry(_) => true,
|
Value::Geometry(_) => true,
|
||||||
Value::Array(v) => !v.value.is_empty(),
|
Value::Array(v) => !v.is_empty(),
|
||||||
Value::Object(v) => !v.is_empty(),
|
Value::Object(v) => !v.is_empty(),
|
||||||
Value::Strand(v) => !v.value.is_empty() && v.value.to_ascii_lowercase() != "false",
|
Value::Strand(v) => !v.value.is_empty() && v.value.to_ascii_lowercase() != "false",
|
||||||
Value::Number(v) => v.is_truthy(),
|
Value::Number(v) => v.is_truthy(),
|
||||||
|
@ -831,14 +831,14 @@ impl Value {
|
||||||
|
|
||||||
pub fn all_equal(&self, other: &Value) -> bool {
|
pub fn all_equal(&self, other: &Value) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => v.value.iter().all(|v| v.equal(other)),
|
Value::Array(v) => v.iter().all(|v| v.equal(other)),
|
||||||
_ => self.equal(other),
|
_ => self.equal(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any_equal(&self, other: &Value) -> bool {
|
pub fn any_equal(&self, other: &Value) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => v.value.iter().any(|v| v.equal(other)),
|
Value::Array(v) => v.iter().any(|v| v.equal(other)),
|
||||||
_ => self.equal(other),
|
_ => self.equal(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -855,21 +855,21 @@ impl Value {
|
||||||
|
|
||||||
pub fn all_fuzzy(&self, other: &Value) -> bool {
|
pub fn all_fuzzy(&self, other: &Value) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => v.value.iter().all(|v| v.fuzzy(other)),
|
Value::Array(v) => v.iter().all(|v| v.fuzzy(other)),
|
||||||
_ => self.fuzzy(other),
|
_ => self.fuzzy(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn any_fuzzy(&self, other: &Value) -> bool {
|
pub fn any_fuzzy(&self, other: &Value) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => v.value.iter().any(|v| v.fuzzy(other)),
|
Value::Array(v) => v.iter().any(|v| v.fuzzy(other)),
|
||||||
_ => self.fuzzy(other),
|
_ => self.fuzzy(other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, other: &Value) -> bool {
|
pub fn contains(&self, other: &Value) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(v) => v.value.iter().any(|v| v.equal(other)),
|
Value::Array(v) => v.iter().any(|v| v.equal(other)),
|
||||||
Value::Strand(v) => match other {
|
Value::Strand(v) => match other {
|
||||||
Value::Strand(w) => v.value.contains(w.as_str()),
|
Value::Strand(w) => v.value.contains(w.as_str()),
|
||||||
_ => v.value.contains(&other.to_strand().as_str()),
|
_ => v.value.contains(&other.to_strand().as_str()),
|
||||||
|
@ -884,8 +884,8 @@ impl Value {
|
||||||
|
|
||||||
pub fn contains_all(&self, other: &Value) -> bool {
|
pub fn contains_all(&self, other: &Value) -> bool {
|
||||||
match other {
|
match other {
|
||||||
Value::Array(v) => v.value.iter().all(|v| match self {
|
Value::Array(v) => v.iter().all(|v| match self {
|
||||||
Value::Array(w) => w.value.iter().any(|w| v.equal(w)),
|
Value::Array(w) => w.iter().any(|w| v.equal(w)),
|
||||||
Value::Geometry(_) => self.contains(v),
|
Value::Geometry(_) => self.contains(v),
|
||||||
_ => false,
|
_ => false,
|
||||||
}),
|
}),
|
||||||
|
@ -895,8 +895,8 @@ impl Value {
|
||||||
|
|
||||||
pub fn contains_any(&self, other: &Value) -> bool {
|
pub fn contains_any(&self, other: &Value) -> bool {
|
||||||
match other {
|
match other {
|
||||||
Value::Array(v) => v.value.iter().any(|v| match self {
|
Value::Array(v) => v.iter().any(|v| match self {
|
||||||
Value::Array(w) => w.value.iter().any(|w| v.equal(w)),
|
Value::Array(w) => w.iter().any(|w| v.equal(w)),
|
||||||
Value::Geometry(_) => self.contains(v),
|
Value::Geometry(_) => self.contains(v),
|
||||||
_ => false,
|
_ => false,
|
||||||
}),
|
}),
|
||||||
|
|
Loading…
Reference in a new issue