Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fixes tests
# Conflicts:
#	sansa-rdf/sansa-rdf-common/src/main/scala/net/sansa_stack/rdf/common/partition/r2rml/R2rmlUtils.scala
  • Loading branch information
LorenzBuehmann committed Jan 19, 2021
1 parent d1c70a6 commit a01e238
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 33 deletions.
Expand Up @@ -26,26 +26,48 @@ object R2rmlUtils {
def createR2rmlMappings(partitioner: RdfPartitioner[RdfPartitionStateDefault],
partition: RdfPartitionStateDefault,
model: Model,
explodeLanguageTags: Boolean): Seq[TriplesMap] = {
explodeLanguageTags: Boolean,
escapeIdentifiers: Boolean): Seq[TriplesMap] = {
createR2rmlMappings(
partitioner,
partition,
x => createDefaultTableName(x), // Map the partition to a name
new SqlEscaperBacktick,
model,
explodeLanguageTags)
explodeLanguageTags,
escapeIdentifiers)
}

def createR2rmlMappings(partitioner: RdfPartitioner[RdfPartitionStateDefault],
partitions: Seq[RdfPartitionStateDefault],
model: Model,
explodeLanguageTags: Boolean): Seq[TriplesMap] = {
explodeLanguageTags: Boolean,
escapeIdentifiers: Boolean): Seq[TriplesMap] = {
partitions
.flatMap(p => createR2rmlMappings(
partitioner,
p,
model,
explodeLanguageTags))
explodeLanguageTags,
escapeIdentifiers))
}

def createR2rmlMappings(partitioner: RdfPartitioner[RdfPartitionStateDefault],
partitions: Seq[RdfPartitionStateDefault],
extractTableName: RdfPartitionStateDefault => String,
sqlEscaper: SqlEscaper,
model: Model,
explodeLanguageTags: Boolean,
escapeIdentifiers: Boolean): Seq[TriplesMap] = {
partitions
.flatMap(p => createR2rmlMappings(
partitioner,
p,
extractTableName,
sqlEscaper,
model,
explodeLanguageTags,
escapeIdentifiers))
}


Expand All @@ -63,48 +85,79 @@ object R2rmlUtils {
* @param outModel The output model
* @param explodeLanguageTags If true then a mapping is generated for each language tag listed in the partition state.
* Otherwise a generic language column is introduces
* @param escapeIdentifiers if all SQL identifiers have to be escaped
* @return The set of {@link TriplesMap}s added to the output model
*/
def createR2rmlMappings(partitioner: RdfPartitioner[RdfPartitionStateDefault],
partitionState: RdfPartitionStateDefault,
extractTableName: RdfPartitionStateDefault => String,
sqlEscaper: SqlEscaper,
outModel: Model,
explodeLanguageTags: Boolean): Seq[TriplesMap] = {
explodeLanguageTags: Boolean,
escapeIdentifiers: Boolean): Seq[TriplesMap] = {
val p = partitionState // Shorthand
val t = partitioner.determineLayout(partitionState).schema

val attrNames = t.members.sorted.collect({ case m: MethodSymbol if m.isCaseAccessor => m.name.toString })
var attrNames = t.members.sorted.collect({ case m: MethodSymbol if m.isCaseAccessor => m.name.toString })
if (escapeIdentifiers) {
attrNames = attrNames.map(sqlEscaper.escapeColumnName)
}

val predicateIri: String = partitionState.predicate
val tableName = extractTableName(partitionState)
var tableName = extractTableName(partitionState)
if (escapeIdentifiers) {
tableName = sqlEscaper.escapeTableName(tableName)
}

if (explodeLanguageTags && attrNames.length == 3) {
val langColSql = sqlEscaper.escapeColumnName(attrNames(2))
val columnsSql = attrNames.slice(0, 2).map(sqlEscaper.escapeColumnName).mkString(", ")

p.languages.map(lang => {
val tableNameSql = sqlEscaper.escapeTableName(tableName)
val langSql = sqlEscaper.escapeStringLiteral(lang)

val escapedColumns = if (escapeIdentifiers) attrNames else attrNames.map(sqlEscaper.escapeColumnName)
val projectedColumns = escapedColumns.slice(0, 2)
val columnsSql = projectedColumns.mkString(", ")
val langColSql = escapedColumns(2)

// if there is only one language tag, we can omit the SQL query with the FILTER on the lang column
if (p.languages.size == 1) {
// TODO put to outer if-else and just add rr:language attribute
// TODO for this case we wouldn'T even need a table with a lang column, as long as the mapping keeps track of the language
val tm: TriplesMap = outModel.createResource.as(classOf[TriplesMap])
val pom: PredicateObjectMap = tm.addNewPredicateObjectMap()
pom.addPredicate(predicateIri)

// create subject map
val sm: SubjectMap = tm.getOrSetSubjectMap()
setTermMapForNode(sm, 0, attrNames, p.subjectType, "", false)

val pom: PredicateObjectMap = tm.addNewPredicateObjectMap()
pom.addPredicate(predicateIri)

// and the object map
val om: ObjectMap = pom.addNewObjectMap()
om.setColumn(attrNames(1))
om.setLanguage(lang)
om.setColumn(escapedColumns(1))
if (p.languages.head.trim.nonEmpty) om.setLanguage(p.languages.head)

tm.getOrSetLogicalTable().asBaseTableOrView().setTableName(tableName)

Seq(tm)
} else {
p.languages.map(lang => {
val tableNameSql = if (escapeIdentifiers) tableName else sqlEscaper.escapeTableName(tableName)
val langSql = sqlEscaper.escapeStringLiteral(lang)

val tm: TriplesMap = outModel.createResource.as(classOf[TriplesMap])

// create subject map
val sm: SubjectMap = tm.getOrSetSubjectMap()
setTermMapForNode(sm, 0, escapedColumns, p.subjectType, "", false)

val pom: PredicateObjectMap = tm.addNewPredicateObjectMap()
pom.addPredicate(predicateIri)

val om: ObjectMap = pom.addNewObjectMap()
om.setColumn(escapedColumns(1))
if (lang.trim.nonEmpty) om.setLanguage(lang)

tm.getOrSetLogicalTable().asR2rmlView().setSqlQuery(s"SELECT $columnsSql FROM $tableNameSql WHERE $langColSql = $langSql")
tm.getOrSetLogicalTable().asR2rmlView().setSqlQuery(s"SELECT $columnsSql FROM $tableNameSql WHERE $langColSql = $langSql")

tm
}).toSeq
tm
}).toSeq
}
} else {
val tm: TriplesMap = outModel.createResource.as(classOf[TriplesMap])
val pom: PredicateObjectMap = tm.addNewPredicateObjectMap()
Expand Down
Expand Up @@ -56,7 +56,7 @@ class RdfPartitionerDefaultTests extends FunSuite {
|
|[ rr:logicalTable [ rr:tableName "http://xmlns.com/foaf/0.1/givenName_XMLSchema#string_lang" ] ;
| rr:predicateObjectMap [ rr:objectMap [ rr:column "o" ;
| rr:langColumn "l"
| rr:languageColumn "l"
| ] ;
| rr:predicate <http://xmlns.com/foaf/0.1/givenName>
| ] ;
Expand All @@ -71,15 +71,15 @@ class RdfPartitionerDefaultTests extends FunSuite {

val model = ModelFactory.createDefaultModel()

val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, model, false)
val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, model, false, false)

// There must be just a single triples map
assert(triplesMaps.size == 1)

val triplesMap = triplesMaps(0)
val actual = triplesMap.getModel

assert(expected.isIsomorphicWith(actual))
assert(expected.isIsomorphicWith(model))
}

test("export partition with lang tags exploded as R2RML should result in a separate TriplesMap per language tag") {
Expand All @@ -89,34 +89,34 @@ class RdfPartitionerDefaultTests extends FunSuite {
"""
| @base <http://www.w3.org/ns/r2rml#> .
|[ <#logicalTable> [ <#sqlQuery> "SELECT `s`, `o` FROM `http://xmlns.com/foaf/0.1/givenName_XMLSchema#string_lang` WHERE `l` = 'fr'" ] ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "o" ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "`o`" ;
| <#language> "fr"
| ] ;
| <#predicate> <http://xmlns.com/foaf/0.1/givenName>
| ] ;
| <#subjectMap> [ <#column> "s" ;
| <#subjectMap> [ <#column> "`s`" ;
| <#datatype> <#IRI>
| ]
|] .
|
|[ <#logicalTable> [ <#sqlQuery> "SELECT `s`, `o` FROM `http://xmlns.com/foaf/0.1/givenName_XMLSchema#string_lang` WHERE `l` = 'de'" ] ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "o" ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "`o`" ;
| <#language> "de"
| ] ;
| <#predicate> <http://xmlns.com/foaf/0.1/givenName>
| ] ;
| <#subjectMap> [ <#column> "s" ;
| <#subjectMap> [ <#column> "`s`" ;
| <#datatype> <#IRI>
| ]
|] .
|
|[ <#logicalTable> [ <#sqlQuery> "SELECT `s`, `o` FROM `http://xmlns.com/foaf/0.1/givenName_XMLSchema#string_lang` WHERE `l` = 'en'" ] ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "o" ;
| <#predicateObjectMap> [ <#objectMap> [ <#column> "`o`" ;
| <#language> "en"
| ] ;
| <#predicate> <http://xmlns.com/foaf/0.1/givenName>
| ] ;
| <#subjectMap> [ <#column> "s" ;
| <#subjectMap> [ <#column> "`s`" ;
| <#datatype> <#IRI>
| ]
|] .
Expand All @@ -129,7 +129,7 @@ class RdfPartitionerDefaultTests extends FunSuite {

val actual = ModelFactory.createDefaultModel()

val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, actual, true)
val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, actual, true, true)

RDFDataMgr.write(System.out, actual, RDFFormat.TURTLE_PRETTY)

Expand All @@ -144,7 +144,7 @@ class RdfPartitionerDefaultTests extends FunSuite {
2, "http://www.w3.org/2001/XMLSchema#string", true, Set("en", "de", "fr"))

val exportModel = ModelFactory.createDefaultModel()
val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, exportModel, true)
val triplesMaps = R2rmlUtils.createR2rmlMappings(RdfPartitionerDefault, partitionState, exportModel, true, true)

// val exportModel = exportModel // RdfPartitionImportExport.exportAsR2RML(RdfPartitionerDefault, partitionState, true)
exportModel.write(System.out, "Turtle", "http://www.w3.org/ns/r2rml#")
Expand Down

0 comments on commit a01e238

Please sign in to comment.