Skip to content

Commit

Permalink
add 'filter' command
Browse files Browse the repository at this point in the history
  • Loading branch information
pchampin committed Nov 22, 2024
1 parent 3b94cbf commit 8f9d2fa
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 15 deletions.
28 changes: 14 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ version = "0.9.0"
features = ["file_url", "http_client", "jsonld", "sparql", "xml"]
# path = "../sophia_rs/sophia"
git = "https://github.com/pchampin/sophia_rs.git"
rev = "00d3cf98"
rev = "3b2a6dc"

[[bin]]
name = "sop"
Expand Down
51 changes: 51 additions & 0 deletions src/filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::convert::Infallible;

use anyhow::Result;
use sophia::{
api::{quad::Spog, sparql::SparqlDataset},
sparql::{SparqlQuery, SparqlWrapper, SparqlWrapperError},
term::ArcTerm,
};

use crate::common::{pipe::PipeSubcommand, quad_handler::QuadHandler, quad_iter::QuadIter};

/// Keep only quads that match a SPARQL expression.
///
/// In the expression, ?s, ?p, ?o and ?g are bound to the subject,
/// predicare, object and graph name of the quad, respectively.
#[derive(clap::Args, Clone, Debug)]
pub struct Args {
/// SPARQL expression
#[arg()]
expression: String,

#[command(subcommand)]
pipeline: Option<PipeSubcommand>,
}

pub fn run(mut quads: QuadIter, args: Args) -> Result<()> {
log::trace!("filter args: {args:#?}");

let ask_query = make_query(&args.expression)?;
let handler = QuadHandler::new(args.pipeline);
handler.handle_quads(QuadIter::new(quads.into_iter().filter_map(|res| {
let Ok(quad) = res else {
return Some(res); // always keep errors
};
let dataset = [quad];
let sparql = SparqlWrapper(&dataset[..]);
let resp = sparql.query(&ask_query).ok()?.into_boolean();
let [quad] = dataset;
resp.then(|| Ok(quad))
})))
}

fn make_query(
expression: &str,
) -> Result<SparqlQuery<[Spog<ArcTerm>]>, SparqlWrapperError<Infallible>> {
let empty_dataset: [Spog<ArcTerm>; 0] = [];
let sparql = SparqlWrapper(&empty_dataset[..]);
sparql.prepare_query(&format!(
"ASK {{ {{ ?s ?p ?o }} UNION {{ GRAPH ?g {{ ?s ?p ?o }} }} FILTER ({expression}) }}"
))
}
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use common::quad_iter::QuadIter;

mod canonicalize;
mod common;
mod filter;
mod merge_default_graph;
mod parse;
mod query;
Expand Down Expand Up @@ -42,6 +43,8 @@ enum SourceSubcommand {
enum SinkSubcommand {
#[command(visible_aliases=["c", "c14n"], aliases=["ca", "can"])]
Canonicalize(canonicalize::Args),
#[command(visible_aliases=["f"], aliases=["fi", "fil"])]
Filter(filter::Args),
#[command(visible_aliases=["m", "merge"], aliases=["me", "mer"])]
MergeDefaultGraph(merge_default_graph::Args),
#[command(visible_aliases=["q"], aliases=["qu", "que"])]
Expand All @@ -54,6 +57,7 @@ impl SinkSubcommand {
pub fn handle_quads(self, quads: QuadIter) -> Result<()> {
match self {
Self::Canonicalize(args) => canonicalize::run(quads, args),
Self::Filter(args) => filter::run(quads, args),
Self::MergeDefaultGraph(args) => merge_default_graph::run(quads, args),
Self::Query(args) => query::run(quads, args),
Self::Serialize(args) => serialize::run(quads, args),
Expand Down

0 comments on commit 8f9d2fa

Please sign in to comment.