tx triples
parent
51a27163c6
commit
a9c1676e24
@ -1 +0,0 @@
|
|||||||
|
|
@ -0,0 +1,122 @@
|
|||||||
|
use crate::data::id::{AttrId, EntityId, Validity};
|
||||||
|
use crate::data::keyword::Keyword;
|
||||||
|
use crate::data::triple::StoreOp;
|
||||||
|
use crate::data::value::Value;
|
||||||
|
use crate::runtime::transact::SessionTx;
|
||||||
|
use anyhow::Result;
|
||||||
|
use serde_json::Map;
|
||||||
|
|
||||||
|
pub(crate) struct Triple<'a> {
|
||||||
|
id: EntityId,
|
||||||
|
attr: AttrId,
|
||||||
|
value: Value<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Quintuple<'a> {
|
||||||
|
triple: Triple<'a>,
|
||||||
|
op: StoreOp,
|
||||||
|
validity: Validity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum TxError {
|
||||||
|
#[error("Error decoding {0}: {1}")]
|
||||||
|
Decoding(serde_json::Value, String),
|
||||||
|
#[error("triple length error")]
|
||||||
|
TripleLength,
|
||||||
|
#[error("attribute not found: {0}")]
|
||||||
|
AttrNotFound(Keyword),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionTx {
|
||||||
|
/// Requests are like these
|
||||||
|
/// ```json
|
||||||
|
/// {"tx": [...], "comment": "a comment", "since": timestamp}
|
||||||
|
/// ```
|
||||||
|
/// each line in `tx` is `{"put: ...}`, `{"retract": ...}`, `{"erase": ...}` or `{"ensure": ...}`
|
||||||
|
/// these can also have a `from` field, overriding the timestamp
|
||||||
|
/// the dots can be triples
|
||||||
|
/// ```json
|
||||||
|
/// [12345, ":x/y", 12345]
|
||||||
|
/// ```
|
||||||
|
/// triples with tempid
|
||||||
|
/// ```json
|
||||||
|
/// ["tempid1", ":x/y", 12345]
|
||||||
|
/// ```
|
||||||
|
/// objects format
|
||||||
|
/// ```json
|
||||||
|
/// {
|
||||||
|
/// "_id": 12345,
|
||||||
|
/// "_tempid": "xyzwf",
|
||||||
|
/// "ns/fieldname": 111
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// nesting is allowed for values of type `ref` and `component`
|
||||||
|
pub fn parse_tx_requests<'a>(
|
||||||
|
&mut self,
|
||||||
|
req: &'a serde_json::Value,
|
||||||
|
) -> Result<(Vec<Quintuple<'a>>, String)> {
|
||||||
|
let map = req
|
||||||
|
.as_object()
|
||||||
|
.ok_or_else(|| TxError::Decoding(req.clone(), "expected object".to_string()))?;
|
||||||
|
let items = map
|
||||||
|
.get("tx")
|
||||||
|
.ok_or_else(|| TxError::Decoding(req.clone(), "expected field 'tx'".to_string()))?
|
||||||
|
.as_array()
|
||||||
|
.ok_or_else(|| {
|
||||||
|
TxError::Decoding(
|
||||||
|
req.clone(),
|
||||||
|
"expected field 'tx' to be an array".to_string(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let default_since = match map.get("since") {
|
||||||
|
None => Validity::current(),
|
||||||
|
Some(v) => v.try_into()?,
|
||||||
|
};
|
||||||
|
let comment = match map.get("comment") {
|
||||||
|
None => "".to_string(),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
let mut collected = Vec::with_capacity(items.len());
|
||||||
|
for item in items {
|
||||||
|
collected.push(self.parse_tx_request_item(item, default_since)?)
|
||||||
|
}
|
||||||
|
Ok((collected, comment))
|
||||||
|
}
|
||||||
|
fn parse_tx_request_item<'a>(
|
||||||
|
&mut self,
|
||||||
|
item: &'a serde_json::Value,
|
||||||
|
default_since: Validity,
|
||||||
|
) -> Result<Quintuple<'a>> {
|
||||||
|
if let Some(arr) = item.as_array() {
|
||||||
|
return self.parse_tx_request_arr(arr, default_since);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(obj) = item.as_object() {
|
||||||
|
return self.parse_tx_request_obj(obj, default_since);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(TxError::Decoding(item.clone(), "expected object or array".to_string()).into())
|
||||||
|
}
|
||||||
|
fn parse_tx_request_arr<'a>(
|
||||||
|
&mut self,
|
||||||
|
item: &'a [serde_json::Value],
|
||||||
|
default_since: Validity,
|
||||||
|
) -> Result<Quintuple<'a>> {
|
||||||
|
match item {
|
||||||
|
[eid, attr_kw, val] => {
|
||||||
|
let kw: Keyword = attr_kw.try_into()?;
|
||||||
|
let attr = self.attr_by_kw(&kw)?.ok_or(TxError::AttrNotFound(kw))?;
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
vs => Err(TxError::TripleLength.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn parse_tx_request_obj<'a>(
|
||||||
|
&mut self,
|
||||||
|
item: &'a Map<String, serde_json::Value>,
|
||||||
|
default_since: Validity,
|
||||||
|
) -> Result<Quintuple<'a>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue