hsparql 0.2.3 → 0.2.4
raw patch · 4 files changed
+65/−9 lines, 4 filesdep ~wai
Dependency ranges changed: wai
Files
- Database/HSparql/Connection.hs +26/−0
- Database/HSparql/QueryGenerator.hs +31/−2
- hsparql.cabal +3/−3
- tests/AllTests.hs +5/−4
Database/HSparql/Connection.hs view
@@ -4,6 +4,7 @@ , selectQuery , constructQuery , askQuery+ , updateQuery , describeQuery ) where@@ -73,6 +74,12 @@ | s == "false" = False | otherwise = error $ "Unexpected Ask response: " ++ s +-- |Parses the response from a SPARQL UPDATE query. An empty body is expected+parseUpdate :: String -> Bool+parseUpdate s+ | s == "" = True+ | otherwise = error $ "Unexpected Update response: " ++ s+ -- |Connect to remote 'EndPoint' and find all possible bindings for the -- 'Variable's in the 'SelectQuery' action. selectQuery :: Database.HSparql.Connection.EndPoint -> Query SelectQuery -> IO (Maybe [[BindingValue]])@@ -96,6 +103,25 @@ request = replaceHeader HdrUserAgent "hsparql-client" (getRequest uri) response <- simpleHTTP request >>= getResponseBody return $ parseAsk response+++-- |Connect to remote 'EndPoint' and find all possible bindings for the+-- 'Variable's in the 'SelectQuery' action.+updateQuery :: Database.HSparql.Connection.EndPoint -> Query UpdateQuery -> IO Bool+updateQuery ep q = do+ let uri = ep+ body = createUpdateQuery q+ h1 = mkHeader HdrContentLength $ show (length body)+ h2 = mkHeader HdrContentType "application/sparql-update"+ h3 = mkHeader HdrUserAgent "hsparql-client"+ request = Request { rqURI = fromJust $ parseURI uri+ , rqHeaders = [h1,h2,h3]+ , rqMethod = POST+ , rqBody = body+ }+ response <- simpleHTTP request >>= getResponseBody+-- return $ structureContent response+ return $ parseUpdate response -- |Connect to remote 'EndPoint' and construct 'TriplesGraph' from given
Database/HSparql/QueryGenerator.hs view
@@ -6,6 +6,7 @@ createSelectQuery , createConstructQuery , createAskQuery+ , createUpdateQuery , createDescribeQuery -- * Query Actions , prefix@@ -13,6 +14,7 @@ , Database.HSparql.QueryGenerator.triple , constructTriple , askTriple+ , updateTriple , describeIRI , optional , union@@ -65,6 +67,7 @@ , SelectQuery(..) , ConstructQuery(..) , AskQuery(..)+ , UpdateQuery(..) , DescribeQuery(..) ) where@@ -108,6 +111,14 @@ query <- q modify $ \s -> s { askTriples = queryAsk query, queryType = AskType } +-- |Execute a 'Update Query' action, returning the 'String' representation of the query.+createUpdateQuery :: Query UpdateQuery -> String+createUpdateQuery q = execQuery specifyType qshow+ where specifyType :: Query ()+ specifyType = do+ query <- q+ modify $ \s -> s { updateTriples = queryUpdate query, queryType = UpdateType }+ -- |Execute a 'Describe Query' action, returning the 'String' representation of the query. createDescribeQuery :: Query DescribeQuery -> String createDescribeQuery q = execQuery specifyType qshow@@ -152,6 +163,12 @@ modify $ \s -> s { askTriples = appendTriple t (askTriples s) } return t +updateTriple :: (TermLike a, TermLike b, TermLike c) => a -> b -> c -> Query Pattern+updateTriple a b c = do+ let t = QTriple (varOrTerm a) (varOrTerm b) (varOrTerm c) -- TODO: should only allow terms+ modify $ \s -> s { updateTriples = appendTriple t (updateTriples s) }+ return t+ describeIRI :: IRIRef -> Query IRIRef describeIRI newIri = do modify $ \s -> s { describeURI = Just newIri }@@ -192,6 +209,7 @@ (.:.) :: Prefix -> T.Text -> IRIRef (.:.) = PrefixedName + -- Duplicate handling -- |Set duplicate handling to 'Distinct'. By default, there are no reductions.@@ -366,6 +384,7 @@ , pattern = GroupGraphPattern [] , constructTriples = [] , askTriples = []+ , updateTriples = [] , describeURI = Nothing , duplicates = NoLimits , ordering = []@@ -448,15 +467,16 @@ , pattern :: GroupGraphPattern , constructTriples :: [Pattern] -- QTriple , askTriples :: [Pattern]+ , updateTriples :: [Pattern] , describeURI :: Maybe IRIRef , duplicates :: Duplicates , ordering :: [OrderBy] } -data QueryType = SelectType | ConstructType | AskType | DescribeType | TypeNotSet+data QueryType = SelectType | ConstructType | AskType | UpdateType | DescribeType | TypeNotSet -data QueryForm = SelectForm QueryData | ConstructForm QueryData | AskForm QueryData | DescribeForm QueryData+data QueryForm = SelectForm QueryData | ConstructForm QueryData | AskForm QueryData | UpdateForm QueryData | DescribeForm QueryData data ConstructQuery = ConstructQuery { queryConstructs :: [Pattern] }@@ -464,6 +484,9 @@ data AskQuery = AskQuery { queryAsk :: [Pattern] } +data UpdateQuery = UpdateQuery+ { queryUpdate :: [Pattern] }+ data SelectQuery = SelectQuery { queryVars :: [Variable] } @@ -580,6 +603,8 @@ qshow (AskForm qd) = "ASK { " ++ qshow (askTriples qd) ++ " }" + qshow (UpdateForm qd) = "INSERT DATA { " ++ qshow (updateTriples qd) ++ " }"+ qshow (DescribeForm qd) = "DESCRIBE " ++ qshow (describeURI qd) instance QueryShow QueryData where@@ -609,6 +634,10 @@ AskType -> unwords [ qshow (prefixes qd) , qshow (AskForm qd)+ ]+ UpdateType -> + unwords [ qshow (prefixes qd)+ , qshow (UpdateForm qd) ] in query
hsparql.cabal view
@@ -1,12 +1,12 @@ Name: hsparql Homepage: https://github.com/robstewart57/hsparql-Version: 0.2.3+Version: 0.2.4 Synopsis: A SPARQL query generator and DSL, and a client to query a SPARQL server. Category: Database Description: hsparql includes a DSL to easily create queries, as well as methods to submit those queries to a SPARQL server, returning the results as simple- Haskell data structures.+ Haskell data structures. Supports SELECT, CONSTRUCT, ASK and UPDATE queries. Example queries are included in the tests: <https://github.com/robstewart57/hsparql/blob/master/tests/DBPedia.hs>.@@ -46,7 +46,7 @@ , HUnit , test-framework , test-framework-hunit- , wai+ , wai >= 2.0.0 , warp hs-source-dirs: Database, tests extensions: OverloadedStrings, FlexibleInstances
tests/AllTests.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} module Main where @@ -31,7 +32,7 @@ -> describeResponse otherwise -> error "Unexpected URI"- selectResponse = ResponseFile status200 [("Content-Type", "application/sparql-results+xml")] "tests/fixtures/sparql_select_response.xml" Nothing- askResponse = ResponseFile status200 [("Content-Type", "text/plain")] "tests/fixtures/sparql_ask_response.text" Nothing- constructResponse = ResponseFile status200 [("Content-Type", "text/turtle")] "tests/fixtures/sparql_construct_response.ttl" Nothing- describeResponse = ResponseFile status200 [("Content-Type", "text/turtle")] "tests/fixtures/sparql_describe_response.ttl" Nothing+ selectResponse = responseFile status200 [("Content-Type", "application/sparql-results+xml")] "tests/fixtures/sparql_select_response.xml" Nothing+ askResponse = responseFile status200 [("Content-Type", "text/plain")] "tests/fixtures/sparql_ask_response.text" Nothing+ constructResponse = responseFile status200 [("Content-Type", "text/turtle")] "tests/fixtures/sparql_construct_response.ttl" Nothing+ describeResponse = responseFile status200 [("Content-Type", "text/turtle")] "tests/fixtures/sparql_describe_response.ttl" Nothing