hsparql 0.0 → 0.1
raw patch · 3 files changed
+153/−15 lines, 3 filesdep −containersPVP ok
version bump matches the API change (PVP)
Dependencies removed: containers
API changes (from Hackage documentation)
- Database.HSparql.Connection: sparqlResult :: String -> QName
- Database.HSparql.Connection: structureContent :: String -> Maybe [[BindingValue]]
- Database.HSparql.QueryGenerator: Add :: Operation
- Database.HSparql.QueryGenerator: AndExpr :: [Expr] -> Expr
- Database.HSparql.QueryGenerator: Asc :: Expr -> OrderBy
- Database.HSparql.QueryGenerator: BooleanLiteralTerm :: Bool -> GraphTerm
- Database.HSparql.QueryGenerator: BoundFunc :: Function
- Database.HSparql.QueryGenerator: BuiltinCall :: Function -> [Expr] -> Expr
- Database.HSparql.QueryGenerator: DataTypeFunc :: Function
- Database.HSparql.QueryGenerator: Desc :: Expr -> OrderBy
- Database.HSparql.QueryGenerator: Distinct :: Duplicates
- Database.HSparql.QueryGenerator: Divide :: Operation
- Database.HSparql.QueryGenerator: Equal :: Relation
- Database.HSparql.QueryGenerator: Filter :: Expr -> Pattern
- Database.HSparql.QueryGenerator: GreaterThan :: Relation
- Database.HSparql.QueryGenerator: GreaterThanOrEqual :: Relation
- Database.HSparql.QueryGenerator: GroupGraphPattern :: [Pattern] -> GroupGraphPattern
- Database.HSparql.QueryGenerator: IRIRef :: String -> IRIRef
- Database.HSparql.QueryGenerator: IRIRefTerm :: IRIRef -> GraphTerm
- Database.HSparql.QueryGenerator: IsBlankFunc :: Function
- Database.HSparql.QueryGenerator: IsIRIFunc :: Function
- Database.HSparql.QueryGenerator: IsLiteralFunc :: Function
- Database.HSparql.QueryGenerator: IsURIFunc :: Function
- Database.HSparql.QueryGenerator: LangFunc :: Function
- Database.HSparql.QueryGenerator: LangMatchesFunc :: Function
- Database.HSparql.QueryGenerator: LessThan :: Relation
- Database.HSparql.QueryGenerator: LessThanOrEqual :: Relation
- Database.HSparql.QueryGenerator: Multiply :: Operation
- Database.HSparql.QueryGenerator: NegatedExpr :: Expr -> Expr
- Database.HSparql.QueryGenerator: NoLimits :: Duplicates
- Database.HSparql.QueryGenerator: NotEqual :: Relation
- Database.HSparql.QueryGenerator: NumericExpr :: NumericExpr -> Expr
- Database.HSparql.QueryGenerator: NumericLiteralExpr :: Integer -> NumericExpr
- Database.HSparql.QueryGenerator: NumericLiteralTerm :: Integer -> GraphTerm
- Database.HSparql.QueryGenerator: OperationExpr :: Operation -> Expr -> Expr -> NumericExpr
- Database.HSparql.QueryGenerator: OptionalGraphPattern :: GroupGraphPattern -> Pattern
- Database.HSparql.QueryGenerator: OrExpr :: [Expr] -> Expr
- Database.HSparql.QueryGenerator: Prefix :: Int -> IRIRef -> Prefix
- Database.HSparql.QueryGenerator: PrefixedName :: Prefix -> String -> IRIRef
- Database.HSparql.QueryGenerator: QueryData :: Int -> [Prefix] -> Int -> [Variable] -> GroupGraphPattern -> Duplicates -> [OrderBy] -> QueryData
- Database.HSparql.QueryGenerator: RDFLiteral :: String -> RDFLiteral
- Database.HSparql.QueryGenerator: RDFLiteralIRIRef :: String -> IRIRef -> RDFLiteral
- Database.HSparql.QueryGenerator: RDFLiteralLang :: String -> String -> RDFLiteral
- Database.HSparql.QueryGenerator: RDFLiteralTerm :: RDFLiteral -> GraphTerm
- Database.HSparql.QueryGenerator: Reduced :: Duplicates
- Database.HSparql.QueryGenerator: RegexFunc :: Function
- Database.HSparql.QueryGenerator: RelationalExpr :: Relation -> Expr -> Expr -> Expr
- Database.HSparql.QueryGenerator: SameTermFunc :: Function
- Database.HSparql.QueryGenerator: StrFunc :: Function
- Database.HSparql.QueryGenerator: Subtract :: Operation
- Database.HSparql.QueryGenerator: Term :: GraphTerm -> VarOrTerm
- Database.HSparql.QueryGenerator: Triple :: VarOrTerm -> VarOrTerm -> VarOrTerm -> Pattern
- Database.HSparql.QueryGenerator: UnionGraphPattern :: GroupGraphPattern -> GroupGraphPattern -> Pattern
- Database.HSparql.QueryGenerator: Var :: Variable -> VarOrTerm
- Database.HSparql.QueryGenerator: VarOrTermExpr :: VarOrTerm -> Expr
- Database.HSparql.QueryGenerator: Variable :: Int -> Variable
- Database.HSparql.QueryGenerator: appendPattern :: Pattern -> GroupGraphPattern -> GroupGraphPattern
- Database.HSparql.QueryGenerator: builtinFunc1 :: Function -> BuiltinFunc1
- Database.HSparql.QueryGenerator: builtinFunc2 :: Function -> BuiltinFunc2
- Database.HSparql.QueryGenerator: class QueryShow a
- Database.HSparql.QueryGenerator: class TermLike a
- Database.HSparql.QueryGenerator: data Duplicates
- Database.HSparql.QueryGenerator: data Expr
- Database.HSparql.QueryGenerator: data Function
- Database.HSparql.QueryGenerator: data GraphTerm
- Database.HSparql.QueryGenerator: data GroupGraphPattern
- Database.HSparql.QueryGenerator: data IRIRef
- Database.HSparql.QueryGenerator: data NumericExpr
- Database.HSparql.QueryGenerator: data Operation
- Database.HSparql.QueryGenerator: data OrderBy
- Database.HSparql.QueryGenerator: data Pattern
- Database.HSparql.QueryGenerator: data Prefix
- Database.HSparql.QueryGenerator: data QueryData
- Database.HSparql.QueryGenerator: data RDFLiteral
- Database.HSparql.QueryGenerator: data Relation
- Database.HSparql.QueryGenerator: data VarOrTerm
- Database.HSparql.QueryGenerator: duplicates :: QueryData -> Duplicates
- Database.HSparql.QueryGenerator: execQuery :: Query a -> (QueryData -> b) -> b
- Database.HSparql.QueryGenerator: expr :: (TermLike a) => a -> Expr
- Database.HSparql.QueryGenerator: operation :: (TermLike a, TermLike b) => Operation -> a -> b -> Expr
- Database.HSparql.QueryGenerator: ordering :: QueryData -> [OrderBy]
- Database.HSparql.QueryGenerator: pattern :: QueryData -> GroupGraphPattern
- Database.HSparql.QueryGenerator: prefixIdx :: QueryData -> Int
- Database.HSparql.QueryGenerator: prefixes :: QueryData -> [Prefix]
- Database.HSparql.QueryGenerator: queryData :: QueryData
- Database.HSparql.QueryGenerator: relation :: (TermLike a, TermLike b) => Relation -> a -> b -> Expr
- Database.HSparql.QueryGenerator: type BuiltinFunc2 = (TermLike a, TermLike b) => a -> b -> Expr
- Database.HSparql.QueryGenerator: varOrTerm :: (TermLike a) => a -> VarOrTerm
- Database.HSparql.QueryGenerator: vars :: QueryData -> [Variable]
- Database.HSparql.QueryGenerator: varsIdx :: QueryData -> Int
+ Database.HSparql.Connection: query :: EndPoint -> Query [Variable] -> IO (Maybe [[BindingValue]])
Files
- Database/HSparql/Connection.hs +19/−7
- Database/HSparql/QueryGenerator.hs +133/−6
- hsparql.cabal +1/−2
Database/HSparql/Connection.hs view
@@ -1,4 +1,9 @@-module Database.HSparql.Connection where+module Database.HSparql.Connection+ ( EndPoint+ , BindingValue(..)+ , query+ )+where import Control.Monad import Data.Maybe@@ -7,18 +12,23 @@ import Database.HSparql.QueryGenerator +-- |URI of the SPARQL endpoint. type EndPoint = String -data BindingValue = URI String- | Literal String- | TypedLiteral String String -- value, type- | LangLiteral String String -- value, lang - | Unbound+-- |Local representations of incoming XML results.+data BindingValue = URI String -- ^Absolute reference to remote resource.+ | Literal String -- ^Simple literal string.+ | TypedLiteral String String -- ^Literal element with type resource+ | LangLiteral String String -- ^Literal element with language resource+ | Unbound -- ^Unbound result value deriving (Show, Eq) +-- |Base 'QName' for results with a SPARQL-result URI specified. sparqlResult :: String -> QName sparqlResult s = (unqual s) { qURI = Just "http://www.w3.org/2005/sparql-results#" } +-- |Transform the 'String' result from the HTTP request into a two-dimensional+-- table storing the bindings for each variable in each row. structureContent :: String -> Maybe [[BindingValue]] structureContent s = do e <- doc@@ -49,7 +59,9 @@ langAttr :: QName langAttr = blank_name { qName = "lang", qPrefix = Just "xml" } --- query :: EndPoint -> Query [Variable] -> IO (Maybe [[Element]])+-- |Connect to remote 'EndPoint' and find all possible bindings for the+-- 'Variable's in the 'Query' action.+query :: EndPoint -> Query [Variable] -> IO (Maybe [[BindingValue]]) query ep q = do let uri = ep ++ "?" ++ urlEncodeVars [("query", createQuery q)] request = replaceHeader HdrUserAgent "hsparql-client" (getRequest uri)
Database/HSparql/QueryGenerator.hs view
@@ -1,15 +1,79 @@ {-# LANGUAGE ExtendedDefaultRules, FlexibleInstances, Rank2Types #-}-module Database.HSparql.QueryGenerator where +-- |The query generator DSL for SPARQL, used when connecting to remote+-- endpoints.+module Database.HSparql.QueryGenerator+ ( -- * Creating Queries+ createQuery++ -- * Query Actions+ , prefix+ , var+ , triple+ , optional+ , union+ , filterExpr++ -- ** Duplicate handling+ , distinct+ , reduced++ -- ** Order handling+ , orderNext+ , orderNextAsc+ , orderNextDesc++ -- ** Auxiliary+ , (.:.)+ , iriRef++ -- * Term Manipulation++ -- ** Operations+ , (.+.), (.-.), (.*.), (./.)++ -- ** Relations+ , (.==.), (.!=.), (.<.), (.>.), (.<=.), (.>=.)++ -- ** Negation+ , notExpr++ -- ** Builtin Functions+ , str+ , lang+ , langMatches+ , datatype+ , bound+ , sameTerm+ , isIRI+ , isURI+ , isBlank+ , isLiteral+ , regex++ -- * Printing Queries+ , qshow++ -- * Types+ , Query+ , Variable+ )+where+ import Control.Monad.State import Data.List (intercalate) -- State monads++-- |The 'State' monad applied to 'QueryData'. type Query a = State QueryData a +-- |Execute a 'Query' action, starting with the empty 'queryData', then process+-- the resulting 'QueryData'. execQuery :: Query a -> (QueryData -> b) -> b execQuery q f = f $ execState q queryData +-- |Execute a 'Query' action, returning the 'String' representation of the query. createQuery :: Query [Variable] -> String createQuery q = execQuery specifyVars qshow where specifyVars :: Query ()@@ -17,23 +81,31 @@ modify $ \s -> s { vars = vs } -- Manipulate data within monad++-- |Add a prefix to the query, given an IRI reference, and return it. prefix :: IRIRef -> Query Prefix prefix ref = do n <- gets prefixIdx let p = Prefix n ref modify $ \s -> s { prefixIdx = n + 1, prefixes = p : prefixes s } return p +-- |Create and return a variable to the query, usable in later expressions. var :: Query Variable var = do n <- gets varsIdx modify $ \s -> s { varsIdx = n + 1 } return $ Variable n +-- |Restrict the query to only results for which values match constants in this+-- triple, or for which the variables can be bound. triple :: (TermLike a, TermLike b, TermLike c) => a -> b -> c -> Query Pattern triple a b c = do let t = Triple (varOrTerm a) (varOrTerm b) (varOrTerm c) modify $ \s -> s { pattern = appendPattern t (pattern s) } return t +-- |Add optional constraints on matches. Variable bindings within the optional+-- action are lost, so variables must always be defined prior to opening the+-- optional block. optional :: Query a -> Query Pattern optional q = do -- Determine the patterns by executing the action on a blank QueryData, and@@ -42,6 +114,8 @@ modify $ \s -> s { pattern = appendPattern option (pattern s) } return option +-- |Add a union structure to the query pattern. As with 'optional' blocks,+-- variables must be defined prior to the opening of any block. union :: Query a -> Query b -> Query Pattern union q1 q2 = do let p1 = execQuery q1 pattern@@ -50,6 +124,7 @@ modify $ \s -> s { pattern = appendPattern union (pattern s) } return union +-- |Restrict results to only those for which the given expression is true. filterExpr :: (TermLike a) => a -> Query Pattern filterExpr e = do let f = Filter (expr e)@@ -57,26 +132,42 @@ return f -- Random auxiliary++-- |Form a 'PrefixedName' 'IRIRef', with the 'Prefix' and reference name. (.:.) :: Prefix -> String -> IRIRef (.:.) = PrefixedName +-- |Create an 'IRIRef' with an absolute reference to the address at which it is+-- located. iriRef :: String -> IRIRef iriRef = IRIRef -- Duplicate handling++-- |Set duplicate handling to 'Distinct'. By default, there are no reductions. distinct :: Query Duplicates distinct = do modify $ \s -> s { duplicates = Distinct } gets duplicates +-- |Set duplicate handling to 'Reduced'. By default, there are no reductions. reduced :: Query Duplicates reduced = do modify $ \s -> s { duplicates = Reduced } gets duplicates -- Order handling-orderNext, orderNextAsc, orderNextDesc :: (TermLike a) => a -> Query ()++-- |Alias of 'orderNextAsc'.+orderNext :: (TermLike a) => a -> Query () orderNext = orderNextAsc +-- |Order the results, after any previous ordering, based on the term, in+-- ascending order.+orderNextAsc :: (TermLike a) => a -> Query () orderNextAsc x = do modify $ \s -> s { ordering = (ordering s) ++ [Asc $ expr x] }++-- |Order the results, after any previous ordering, based on the term, in+-- descending order.+orderNextDesc :: (TermLike a) => a -> Query () orderNextDesc x = do modify $ \s -> s { ordering = (ordering s) ++ [Desc $ expr x] } -- Permit variables and values to seemlessly be put into argument for 'triple'@@ -117,25 +208,59 @@ operation :: (TermLike a, TermLike b) => Operation -> a -> b -> Expr operation op x y = NumericExpr $ OperationExpr op (expr x) (expr y) -(.+.), (.-.), (.*.), (./.) :: (TermLike a, TermLike b) => a -> b -> Expr+-- |Add two terms.+(.+.) :: (TermLike a, TermLike b) => a -> b -> Expr (.+.) = operation Add++-- |Find the difference between two terms.+(.-.) :: (TermLike a, TermLike b) => a -> b -> Expr (.-.) = operation Subtract++-- |Multiply two terms.+(.*.) :: (TermLike a, TermLike b) => a -> b -> Expr (.*.) = operation Multiply++-- |Divide two terms.+(./.) :: (TermLike a, TermLike b) => a -> b -> Expr (./.) = operation Divide -- Relations relation :: (TermLike a, TermLike b) => Relation -> a -> b -> Expr relation rel x y = RelationalExpr rel (expr x) (expr y) -(.==.), (.!=.), (.<.), (.>.), (.<=.), (.>=.) :: (TermLike a, TermLike b) => a -> b -> Expr+-- |Create an expression which tests the relationship of the two operands,+-- evaluating their equivalence.+(.==.) :: (TermLike a, TermLike b) => a -> b -> Expr (.==.) = relation Equal++-- |Create an expression which tests the relationship of the two operands,+-- evaluating their equivalence.+(.!=.) :: (TermLike a, TermLike b) => a -> b -> Expr (.!=.) = relation NotEqual-(.<.) = relation LessThan-(.>.) = relation GreaterThan++-- |Create an expression which tests the relationship of the two operands,+-- evaluating their relative value.+(.<.) :: (TermLike a, TermLike b) => a -> b -> Expr+(.<.) = relation LessThan++-- |Create an expression which tests the relationship of the two operands,+-- evaluating their relative value.+(.>.) :: (TermLike a, TermLike b) => a -> b -> Expr+(.>.) = relation GreaterThan++-- |Create an expression which tests the relationship of the two operands,+-- evaluating their relative value.+(.<=.) :: (TermLike a, TermLike b) => a -> b -> Expr (.<=.) = relation LessThanOrEqual++-- |Create an expression which tests the relationship of the two operands,+-- evaluating their relative value.+(.>=.) :: (TermLike a, TermLike b) => a -> b -> Expr (.>=.) = relation GreaterThanOrEqual -- Negation++-- |Negate any term-like expression, for use, e.g., in filtering. notExpr :: (TermLike a) => a -> Expr notExpr = NegatedExpr . expr @@ -195,6 +320,8 @@ -- Query representation class QueryShow a where+ -- |Convert most query-related types to a 'String', most importantly+ -- 'QueryData's. qshow :: a -> String data Duplicates = NoLimits | Distinct | Reduced
hsparql.cabal view
@@ -1,5 +1,5 @@ Name: hsparql-Version: 0.0+Version: 0.1 Synopsis: A SPARQL query generator and DSL, and a client to query a SPARQL server. Category: Database Description:@@ -13,7 +13,6 @@ Build-type: Simple Build-depends: base >= 4 && < 5-Build-depends: containers Build-depends: HTTP >= 4 Build-depends: monads-fd Build-depends: xml