#!/bin/bash

# Relational pipes
# Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


# This is a helper script that could be used as a shebang interpreter for SPARQL files.
# Just set the SPARQL file executable and add the first line comment.
# The endpoint and relation parameters are optional.
# Parameters must be at the beginning of the file before any empty lines.
# Only the first occurrence of each parameter is relevant.
# This interpreter produces a human-readable table if STDOUT is a terminal
# and machine-readable relational data if STDOUT is not a terminal.
# So the stream can be piped to any relational transformation (e.g. relpipe-tr-sql)
# or output filter (e.g. relpipe-out-csv).
#
# Example:
#
#	#!/usr/bin/env rdf-sparql-interpreter.sh
#	# endpoint: https://query.wikidata.org/sparql
#	# relation: few_statements
#	
#	SELECT * WHERE { ?subject ?predicate ?object } LIMIT 3


# Execute the SPARQL query and send the results to the STDOUT
# either raw or formatted as a table depending on whether STDOUT is a terminal or not.
interpret_sparql() {
	if [ -t 1 ] ; then relpipe-in-sparql "$@" | relpipe-out-tabular;
	else relpipe-in-sparql "$@"; fi
}

# Fetches the parameter $2 from file $1.
# Parameters must be formatted as comments: „# name: value“.
# Only the first occurrence is relevant. And empty line terminates processing.
find_parameter() {
	perl -e 'while(<>) { if (/^\s*$/) { last; } elsif (/^# ($ARGV[0]): (.*)$/) { print "$2"; last; } }' "$1" "$2"
}

# Appends the "${options[@]}" array with option $2 taken from the $1 file
# or from environmental variable RELPIPE_IN_SPARQL_${2^^} (the variable has precedence).
prepare_option() {
	variableName="RELPIPE_IN_SPARQL_${2^^}"
	parameterName="$2"
	[[ -n "${!variableName}" ]] && value="${!variableName}" || value="$(find_parameter "$1" "$parameterName")"
	[[ -n "$value" ]] && options+=("--$parameterName" "$value")
}

options=()
prepare_option "$1" endpoint
prepare_option "$1" relation

cat "$1" | interpret_sparql "${options[@]}"
