Add ability to convert a record to another table

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-30 16:21:38 +01:00
parent 9020618a0e
commit b37b027b60
4 changed files with 51 additions and 12 deletions

View file

@ -1,6 +1,4 @@
use crate::sql::idiom::Idiom; use crate::sql::idiom::Idiom;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use msgpack::encode::Error as SerdeError; use msgpack::encode::Error as SerdeError;
use serde::Serialize; use serde::Serialize;
use storekey::decode::Error as DecodeError; use storekey::decode::Error as DecodeError;
@ -205,6 +203,12 @@ pub enum Error {
check: String, check: String,
}, },
/// Found a record id for the record but this is not a valid id
#[error("Found '{value}' for the record ID but this is not a valid id")]
IdInvalid {
value: String,
},
/// There was an error processing a value in parallel /// There was an error processing a value in parallel
#[error("There was an error processing a value in parallel")] #[error("There was an error processing a value in parallel")]
Channel(String), Channel(String),
@ -255,14 +259,8 @@ impl From<channel::RecvError> for Error {
} }
} }
impl From<channel::SendError<Vec<u8>>> for Error { impl<T> From<channel::SendError<T>> for Error {
fn from(e: channel::SendError<Vec<u8>>) -> Error { fn from(e: channel::SendError<T>) -> Error {
Error::Channel(e.to_string())
}
}
impl From<channel::SendError<(Option<Thing>, Value)>> for Error {
fn from(e: channel::SendError<(Option<Thing>, Value)>) -> Error {
Error::Channel(e.to_string()) Error::Channel(e.to_string())
} }
} }

View file

@ -7,7 +7,7 @@ use crate::sql::thing::Thing;
use crate::sql::value::Value; use crate::sql::value::Value;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
static RID: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("id")]); static ID: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("id")]);
impl Value { impl Value {
pub async fn def( pub async fn def(
@ -17,6 +17,6 @@ impl Value {
txn: &Transaction, txn: &Transaction,
val: &Thing, val: &Thing,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.set(ctx, opt, txn, RID.as_ref(), val.clone().into()).await self.set(ctx, opt, txn, ID.as_ref(), val.clone().into()).await
} }
} }

View file

@ -22,5 +22,6 @@ mod object;
mod patch; mod patch;
mod pick; mod pick;
mod replace; mod replace;
mod retable;
mod set; mod set;
mod single; mod single;

View file

@ -0,0 +1,40 @@
use crate::err::Error;
use crate::sql::id::Id;
use crate::sql::part::Part;
use crate::sql::table::Table;
use crate::sql::thing::Thing;
use crate::sql::value::Value;
use once_cell::sync::Lazy;
static ID: Lazy<[Part; 1]> = Lazy::new(|| [Part::from("id")]);
impl Value {
pub fn retable(&self, val: &Table) -> Result<Thing, Error> {
// Fetch the id from the document
let id = match self.pick(&*ID) {
Value::Strand(id) => Thing {
tb: val.to_string(),
id: Id::String(id.0),
},
Value::Number(id) => Thing {
tb: val.to_string(),
id: Id::Number(id),
},
Value::Thing(id) => Thing {
tb: val.to_string(),
id: id.id,
},
Value::None => Thing {
tb: val.to_string(),
id: Id::rand(),
},
id => {
return Err(Error::IdInvalid {
value: id.to_string(),
})
}
};
// Return the record id
Ok(id)
}
}