Skip to content

Commit

Permalink
Merge branch 'development' into 'main'
Browse files Browse the repository at this point in the history
Fixes mapping plan generation by handling edge cases around iri generations and term typing

See merge request rml/proc/algemaploom-rs!14
  • Loading branch information
s-minoo committed Aug 6, 2024
2 parents 866e8af + 46373c1 commit f529b1c
Show file tree
Hide file tree
Showing 24 changed files with 245 additions and 63 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ test_resources/

node_modules/
src/python/ltranslator.so
.idea/
26 changes: 22 additions & 4 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,31 @@ test:
script:
- cargo test --verbose --jobs 1

build:
build-no-bindings:
image: rustdocker/rust:stable
stage: build
script:
- cargo build

build-java:
image: rustdocker/rust:stable
stage: build
script:
- apt update
- apt install -y openjdk-17-jdk curl
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
- sudo apt-get install -y nodejs
- ./build.sh
- ./build_java.sh

build-python:
image: rustdocker/rust:stable
stage: build
script:
- ./build_python.sh

build-nodejs:
image: rustdocker/rust:stable
stage: build
script:
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
- apt update
- sudo apt-get install -y nodejs
- ./build_nodejs.sh
10 changes: 10 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

tab_spaces=4
reorder_imports = true
imports_granularity = "Module"
group_imports = "StdExternalCrate"
struct_field_align_threshold = 20
use_field_init_shorthand = true
enum_discrim_align_threshold = 20
force_multiline_blocks = true
max_width = 80
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ walkdir = "2.4.0"
colored = "2.0.4"
log4rs.workspace = true
log.workspace = true
jni = "0.21.1"
neon = "1.0.0"
pyo3 = { version = "0.21.2", features = ["extension-module"] }
jni = { version = "0.21.1" , optional = true}
neon = { version = "1.0.0", optional = true }
pyo3 = { version = "0.21.2", features = ["extension-module"], optional = true }

[lib]
name = "ltranslator"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ The following features are not supported in translation yet:
4) Functions
5) Conditionals

## Bindings
AlgeMapLoom provides bindings for Java, Python and Node.js.
These can be enabled with the features `jni`, `pyo3` and `neon` respectively.

If you build from source, you can run the `build_java.sh`, `build_python.sh` and `build_nodejs.sh`
scripts respectively.

For usage, check out the [src/java](src/java), [src/python](src/python), and [src/nodejs](src/nodejs) folders.


## Acknowledgement
Expand Down
27 changes: 0 additions & 27 deletions build.sh

This file was deleted.

12 changes: 12 additions & 0 deletions build_java.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

set -e

# Rust build
echo "==> Rust building and bindings"
cargo build --lib --release --features=jni

# Java bindings
echo "==> Java bindings"
# Compile Translator CLI
javac src/java/Translator.java
16 changes: 16 additions & 0 deletions build_nodejs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

set -e

# Rust build
echo "==> Rust building and bindings"
cargo build --lib --release --features=neon

# NodeJS bindings
echo "==> NodeJS bindings"
# Install NodeJS NEON dependencies
npm i
# Execute NEON on Rust library to generate index.node file for NodeJS dynamic library
./node_modules/.bin/neon dist -n translator -v -f target/release/libltranslator.so
# Move index.node to the right folder after generation
mv index.node src/nodejs
12 changes: 12 additions & 0 deletions build_python.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

set -e

# Rust build
echo "==> Rust building and bindings"
cargo build --lib --release --features=pyo3

# Python bindings
echo "==> Python bindings"
# Native import, but requires renaming
cp target/release/libltranslator.so src/python/ltranslator.so
1 change: 1 addition & 0 deletions operator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ pub enum Function {
inner_function: RcExtendFunction,
},
Iri {
base_iri: Option<String>,
inner_function: RcExtendFunction,
},
Literal {
Expand Down
26 changes: 22 additions & 4 deletions rml-interpreter/src/extractors/io.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::io::{BufRead, BufReader, Read, Seek};
use std::path::PathBuf;

use sophia_api::triple::stream::TripleSource;
Expand All @@ -11,6 +11,10 @@ use super::triplesmap_extractor::extract_triples_maps;
use super::ExtractorResult;
use crate::rml_model::Document;

fn extract_base_iri(input: &str) -> Option<String> {
input.strip_prefix("@base").map(|e| e[0..e.len()-1].replace(['<', '>'], "").trim().to_string())
}

pub fn load_graph_bread(buf_read: impl BufRead) -> ExtractorResult<FastGraph> {
match turtle::parse_bufread(buf_read).collect_triples() {
Ok(it) => Ok(it),
Expand Down Expand Up @@ -38,7 +42,11 @@ pub fn load_graph_str(input_str: &str) -> ExtractorResult<FastGraph> {
pub fn parse_str(input_str: &str) -> ExtractorResult<Document> {
let graph = load_graph_str(input_str)?;
let triples_maps = extract_triples_maps(&graph)?;
Ok(Document { triples_maps })
let base_iri = input_str.split('\n').filter_map(extract_base_iri).next();
Ok(Document {
triples_maps,
default_base_iri: base_iri,
})
}

pub fn parse_file(path: PathBuf) -> ExtractorResult<Document> {
Expand All @@ -50,9 +58,19 @@ pub fn parse_file(path: PathBuf) -> ExtractorResult<Document> {
)));
}

let buf_read = BufReader::new(File::open(path)?);
let buf_read = BufReader::new(File::open(path.clone())?);
let triples_maps = extract_triples_maps(&load_graph_bread(buf_read)?)?;
return Ok(Document { triples_maps });

// TODO: Refactor extraction of base iri from RML file <02-08-24, SMO> //
let mut buf_read = BufReader::new(File::open(path)?);
let mut input_string = String::default();
buf_read.read_to_string(&mut input_string)?;
let base_iri = input_string.split('\n').filter_map(extract_base_iri).next();

return Ok(Document {
triples_maps,
default_base_iri: base_iri,
});
}

Err(ParseError::IOErrorStr(format!(
Expand Down
21 changes: 19 additions & 2 deletions rml-interpreter/src/extractors/objectmap_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use super::{ExtractorResult, FromVocab, TermMapExtractor};
use crate::extractors::store::{get_object, get_objects};
use crate::extractors::Extractor;
use crate::rml_model::join::JoinCondition;
use crate::rml_model::term_map::{GraphMap, ObjectMap, TermMapInfo};
use crate::rml_model::term_map::{
GraphMap, ObjectMap, TermMapInfo, TermMapType,
};
use crate::IriString;

fn extract_join_condition(
Expand Down Expand Up @@ -93,8 +95,23 @@ impl TermMapExtractor<ObjectMap> for ObjectMap {

let mut tm_info = tm_info_res?;
if tm_info.term_type.is_none() {
tm_info.term_type = Some(tm_info.term_value.kind());
let mut inferred_term_type = match tm_info.term_map_type {
TermMapType::Reference => Some(TermKind::Literal),
TermMapType::Template => Some(TermKind::Iri),
_ => None,
};

if inferred_term_type.is_none() {
if language.is_some() || data_type.is_some() {
inferred_term_type = Some(TermKind::Literal);
} else {
inferred_term_type = Some(TermKind::Iri);
}
}

tm_info.term_type = inferred_term_type;
}

let graph_maps =
GraphMap::extract_many_from_container(graph_ref, subj_ref)?;

Expand Down
16 changes: 15 additions & 1 deletion rml-interpreter/src/extractors/term_map_info_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ fn extract_term_map_type_value(
));
}

let trip = results_query.pop().ok_or(ParseError::GenericError("Term map doesn't have rr:constant, rr:template, rr:reference, fnml:functionValue nor rr:column.".to_string()))?;
let trip = results_query
.pop()
.ok_or(ParseError::GenericError("Term map doesn't have rr:constant, rr:template, rr:reference, fnml:functionValue nor rr:column.".to_string()))?;

let fetched_pred = trip.p();

let term_map_type_res = match fetched_pred {
Expand Down Expand Up @@ -79,6 +82,7 @@ impl Extractor<TermMapInfo> for TermMapInfo {

let mut term_type = None;

//Explicit term type casting trough rr:termtype predicate
if let Ok(term_type_soph) =
get_object(graph_ref, subj_ref, &term_type_pred)
{
Expand All @@ -100,6 +104,16 @@ impl Extractor<TermMapInfo> for TermMapInfo {
};
}

//Implicit term type derivation for constant-valued term maps
if term_map_type == TermMapType::Constant {
term_type = match term_value {
sophia_term::Term::Iri(_) => Some(TermKind::Iri),
sophia_term::Term::BNode(_) => Some(TermKind::BlankNode),
sophia_term::Term::Literal(_) => Some(TermKind::Literal),
sophia_term::Term::Variable(_) => None,
};
}

let logical_target_iris = get_objects(
graph_ref,
subj_ref,
Expand Down
3 changes: 2 additions & 1 deletion rml-interpreter/src/rml_model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub mod term_map;

#[derive(Debug, Clone)]
pub struct Document {
pub triples_maps: Vec<TriplesMap>,
pub default_base_iri: Option<String>,
pub triples_maps: Vec<TriplesMap>,
}

#[derive(Debug, Clone)]
Expand Down
2 changes: 2 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel="1.77.2"
3 changes: 3 additions & 0 deletions shexml-interpreter/src/parser/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#[cfg(test)]
use std::collections::HashSet;

use chumsky::prelude::*;
use crate::*;

fn assert_parse_expected<T: std::fmt::Debug + PartialEq + Eq>(
parsed_items: Option<T>,
expected_items: Option<T>,
Expand Down
Binary file modified src/java/Translator.class
Binary file not shown.
2 changes: 1 addition & 1 deletion src/java/test.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

cat ../../resources/csv-testcases/RMLTC0001a-CSV/mapping.ttl | java -Djava.library.path=$(pwd)/../../target/debug Translator
cat ../../resources/csv-testcases/RMLTC0001a-CSV/mapping.ttl | java -Djava.library.path=$(pwd)/../../target/release Translator
11 changes: 9 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ pub mod shexml;
pub mod logger;
pub mod api;
pub mod util;

#[cfg(feature = "jni")]
mod java;
mod nodejs;
mod python;

#[cfg(feature = "jni")]
pub use java::*;

#[cfg(feature = "neon")]
mod nodejs;

#[cfg(feature = "pyo3")]
mod python;
Loading

0 comments on commit f529b1c

Please sign in to comment.