Add ObjectPath query language
This commit is contained in:
@@ -130,12 +130,7 @@ impl DbFtsIndex {
|
||||
|
||||
// Try paths in order, using the first value we find
|
||||
'outer: for path in field.path.as_slice() {
|
||||
let segments = path
|
||||
.split('.')
|
||||
.map(|x| Label::new(x).unwrap_or_else(|| panic!("wtf {x}")))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let val = match extractor.query(&segments)? {
|
||||
let val = match extractor.query(path)? {
|
||||
Some(x) => x,
|
||||
None => return Ok(None),
|
||||
};
|
||||
@@ -145,7 +140,7 @@ impl DbFtsIndex {
|
||||
trace!(
|
||||
message = "Skipping field, is null",
|
||||
field = field_name.to_string(),
|
||||
path,
|
||||
?path,
|
||||
// value = ?val
|
||||
);
|
||||
continue;
|
||||
@@ -170,7 +165,7 @@ impl DbFtsIndex {
|
||||
debug!(
|
||||
message = "Skipping field, is array with more than one element",
|
||||
field = field_name.to_string(),
|
||||
path,
|
||||
?path,
|
||||
//value = ?val
|
||||
);
|
||||
continue 'outer;
|
||||
@@ -178,7 +173,7 @@ impl DbFtsIndex {
|
||||
debug!(
|
||||
message = "Skipping field, is empty array",
|
||||
field = field_name.to_string(),
|
||||
path,
|
||||
?path,
|
||||
//value = ?val
|
||||
);
|
||||
continue 'outer;
|
||||
@@ -188,7 +183,7 @@ impl DbFtsIndex {
|
||||
trace!(
|
||||
message = "Skipping field, is null",
|
||||
field = field_name.to_string(),
|
||||
path,
|
||||
?path,
|
||||
//value = ?val
|
||||
);
|
||||
continue 'outer;
|
||||
@@ -197,7 +192,7 @@ impl DbFtsIndex {
|
||||
trace!(
|
||||
message = "Skipping field, is object",
|
||||
field = field_name.to_string(),
|
||||
path,
|
||||
?path,
|
||||
//value = ?val
|
||||
);
|
||||
continue 'outer;
|
||||
|
||||
@@ -71,12 +71,13 @@ fn find_latest_modified(dir: &Path) -> Result<Option<DateTime<Utc>>, std::io::Er
|
||||
});
|
||||
}
|
||||
} else if metadata.is_dir()
|
||||
&& let Some(dir_latest) = find_latest_modified(&path)? {
|
||||
latest = Some(match latest {
|
||||
Some(prev) if prev > dir_latest => prev,
|
||||
_ => dir_latest,
|
||||
});
|
||||
}
|
||||
&& let Some(dir_latest) = find_latest_modified(&path)?
|
||||
{
|
||||
latest = Some(match latest {
|
||||
Some(prev) if prev > dir_latest => prev,
|
||||
_ => dir_latest,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(latest);
|
||||
@@ -107,12 +108,13 @@ fn find_earliest_modified(dir: &Path) -> Result<Option<DateTime<Utc>>, std::io::
|
||||
});
|
||||
}
|
||||
} else if metadata.is_dir()
|
||||
&& let Some(dir_earliest) = find_earliest_modified(&path)? {
|
||||
earliest = Some(match earliest {
|
||||
Some(prev) if prev < dir_earliest => prev,
|
||||
_ => dir_earliest,
|
||||
});
|
||||
}
|
||||
&& let Some(dir_earliest) = find_earliest_modified(&path)?
|
||||
{
|
||||
earliest = Some(match earliest {
|
||||
Some(prev) if prev < dir_earliest => prev,
|
||||
_ => dir_earliest,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(earliest);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use pile_config::Label;
|
||||
use pile_config::objectpath::{ObjectPath, PathSegment};
|
||||
use serde_json::{Map, Value};
|
||||
use smartstring::{LazyCompact, SmartString};
|
||||
|
||||
@@ -32,17 +32,40 @@ impl<I: Item> Clone for PileValue<'_, I> {
|
||||
}
|
||||
|
||||
impl<'a, I: Item> PileValue<'a, I> {
|
||||
pub fn query(&'a self, query: &[Label]) -> Result<Option<&'a Self>, std::io::Error> {
|
||||
pub fn query(&'a self, query: &ObjectPath) -> Result<Option<&'a Self>, std::io::Error> {
|
||||
let mut out = Some(self);
|
||||
|
||||
for q in query {
|
||||
out = match &out {
|
||||
None => return Ok(None),
|
||||
Some(Self::Null) => None,
|
||||
Some(Self::Array(_)) => None,
|
||||
Some(Self::String(_)) => None,
|
||||
Some(Self::Extractor(e)) => e.field(q)?,
|
||||
};
|
||||
for s in &query.segments {
|
||||
match s {
|
||||
PathSegment::Root => out = Some(self),
|
||||
PathSegment::Field(field) => {
|
||||
out = match &out {
|
||||
None => return Ok(None),
|
||||
Some(Self::Null) => None,
|
||||
Some(Self::Array(_)) => None,
|
||||
Some(Self::String(_)) => None,
|
||||
Some(Self::Extractor(e)) => e.field(field)?,
|
||||
}
|
||||
}
|
||||
|
||||
PathSegment::Index(idx) => {
|
||||
out = match &out {
|
||||
None => return Ok(None),
|
||||
Some(Self::Null) => None,
|
||||
Some(Self::Array(v)) => {
|
||||
let idx = if *idx >= 0 {
|
||||
usize::try_from(*idx).ok()
|
||||
} else {
|
||||
usize::try_from(v.len() as i64 - idx).ok()
|
||||
};
|
||||
|
||||
idx.and_then(|idx| v.get(idx))
|
||||
}
|
||||
Some(Self::String(_)) => None,
|
||||
Some(Self::Extractor(_)) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(out);
|
||||
|
||||
Reference in New Issue
Block a user