{- | Module : SPARQLFunctions Author : Manuel Ohlendorf Maintainer : Manuel Ohlendorf Stability : experimental Portability: portable Version : Several functions used for query processing. -} module SPARQLFunctions ( normalizeQuery ,showResult ,getSPARQLQuery ) where import SPARQLDataTypes import RDFDataTypes import SPARQLParser import Text.ParserCombinators.Parsec (parse) import Text.XML.HXT.Arrow -- | normalises the Triple Patterns normalizeTripleP :: TriplePattern -> [TriplePattern] normalizeTripleP (TriplePatN s p o ) = [TriplePatN s p o] normalizeTripleP (TriplePat _ []) = [] normalizeTripleP (TriplePat _ ((_,[]):_)) = [] normalizeTripleP (TriplePat s ((p,[o]):xs)) = (TriplePatN s p o) : normalizeTripleP(TriplePat s xs) normalizeTripleP (TriplePat s ((p,(x:xs)):ys)) = (TriplePatN s p x) : normalizeTripleP (TriplePat s [(p,xs)]) ++ normalizeTripleP (TriplePat s ys) -- | normalises the Pattern elements normalizePatternElement :: PatternElement -> [TriplePattern] normalizePatternElement (PET t) = normalizeTripleP t normalizePatternElement (PEG []) = [] normalizePatternElement (PEG (x:xs)) = normalizePatternElement x ++ normalizePatternElement' xs normalizePatternElement' :: [PatternElement] -> [TriplePattern] normalizePatternElement' [] = [] normalizePatternElement' (x:xs) = normalizePatternElement x ++ normalizePatternElement' xs -- | normalises the graph patterns normalizeGraphPattern :: GraphPattern -> [TriplePattern] normalizeGraphPattern (GraphPattern []) = [] normalizeGraphPattern (GraphPattern (x:xs)) = normalizePatternElement x ++ normalizePatternElement' xs -- | normalises a 'Query' by removing all abbreviations. -- The result is a 'Query' containing a list of simple triple patterns. -- This function has to be called be for query evaluation. normalizeQuery :: Query -> Query normalizeQuery Empty = Empty normalizeQuery (QueryN _ []) = Empty normalizeQuery (QueryN v (x:xs)) = QueryN v (x:xs) normalizeQuery (Query v gp) = QueryN v (normalizeGraphPattern gp) showIt :: [(Either RDFTerm URI)] -> String showIt [] = "" showIt ((Right u) :xs) = '|' : "<" ++ u ++">|\n" ++ showIt xs showIt ((Left r) :xs) = '|' : show r ++"|\n" ++ showIt xs -- | The show function for printing out the result of the query evaluation showResult :: [(Var,[(Either RDFTerm URI)])] -> String showResult [] = "" showResult ((var, xs):ys) = if (xs /=[]) then '\t' : '?':var ++ "\n" ++ (showIt xs) ++"\n"++ (showResult ys) else "" -- | The main entry point, when combining the SPARQL parser with a arrow based programme. -- Executes the SPARQL parser and returns a 'Query'. -- -- Raises an error if the parsing fails and returns a empty 'Query'. -- -- The extra parameter is the query string which will be parsed. -- The arrow input is ignored, the output is the parsed query. getSPARQLQuery :: String -> IOSArrow a Query getSPARQLQuery queryStr = case (parse parseSPARQL "" queryStr) of Left parseError -> (issueFatal ("Syntax error in SPARQL query " ++ show queryStr ++ ": " ++ show parseError) >>> constA (Empty)) Right theQuery -> constA (theQuery)