Stardog RowMapper

Hi,

I've a question regarding rowmapping after getting the result from stardog using snarl. For instance, here https://github.com/stardog-union/stardog-spring/blob/master/stardog-spring/docs/QUICKSTART.md#4-basic-snarltemplate-examples, I could find a Map<String,String> mapper like below.

String sparql = "SELECT ?a ?b WHERE { ?a  <urn:test:b> ?b } LIMIT 5";

List<Map<String,String>> results = snarlTemplate.query(sparql, new RowMapper<Map<String,String>>() {

    @Override
    public Map<String,String> mapRow(BindingSet bindingSet) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("a", bindingSet.getValue("a").stringValue());
        map.put("b", bindingSet.getValue("b").stringValue());
        return map;
    } 
});

Let's say I'd like to have a Map<String,Object>, in which the object can be of different datatypes like string, float, boolean, IRI, etc. something like the mapping that you do very well in the stardog studio like below:
Screen Shot 2022-10-19 at 5.25.07 pm
It would be great if you could let me know how you implemented this mapping. I could not find its source code.

Hi,

If you don't have a specific need to use the SnarlTemplate from stardog-spring, we recommend using the SNARL protocol in java directly by just instantiating your Connection (versus having Spring do it for you) like so:

String sparql = "SELECT ?a ?b WHERE { ?a  <urn:test:b> ?b } LIMIT 5";
		try (Connection c = ConnectionConfiguration.to("myDb").server("http://localhost:5820").credentials("admin", "admin").connect();
		     SelectQueryResult result = c.select(sparql).execute()) {
...
}

This SelectQueryResult is an iterable collection of BindingSet objects, which acts as a map of String to Value, Value being an RDF term that encompasses IRIs and Literals. You may notice that you could essentially see this as a List<Map<String, Value>>, which is what snarlTemplate.query is ultimately using under the hood, but getting it directly from the Connection allows you to process it however you'd like:

BindingSet bs = result.next();
			Value a = bs.get("a");
			if (a instanceof Literal) {
				switch (((Literal) a).datatype()) {
					case BOOLEAN:
						// Boolean processing
					case FLOAT:
						// Float processing
					//...
					default:
						// Process as String
				}
			}
			else if (a instanceof IRI) {
				Value.lex(a); // produces a String representation of the IRI 
			}
1 Like