Implement SQL Array as a newtype tuple struct

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-04 17:14:40 +01:00
parent 3ee1ddb5b1
commit 143da56728
20 changed files with 166 additions and 193 deletions

View file

@ -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?,

View file

@ -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?,

View file

@ -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));
} }

View file

@ -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();

View file

@ -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),

View file

@ -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()),

View file

@ -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),

View file

@ -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);
} }
} }

View file

@ -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 {

View file

@ -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),

View file

@ -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,

View file

@ -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(())
} }

View file

@ -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;

View file

@ -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))))

View file

@ -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))))

View file

@ -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())
} }
}, },

View file

@ -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,

View file

@ -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(())
} }

View file

@ -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,
}, },

View file

@ -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,
}), }),