module Redland.Util where
import Foreign
import Control.Monad
import Data.Maybe
import Redland.LowLevel
import Redland.MidLevel
withHash :: ForeignPtr RedlandWorld
-> String
-> [(String, String)]
-> (ForeignPtr RedlandHash -> IO a)
-> IO a
withHash world factory l f =
withNew (redlandHash world factory) $ \hash -> do
mapM_ (uncurry (hashPutStrings hash)) l
f hash
withStatements :: ForeignPtr RedlandWorld
-> ForeignPtr RedlandModel
-> Triple
-> ([Triple] -> IO a)
-> IO a
withStatements world model t f =
withNew (tripleToStatement world t) $ \statement ->
withNew (modelFindStatements model statement) $
streamToList >=> f
data Node = BlankNode String
| LiteralNode String
| ResourceNode String
deriving (Eq, Show)
redlandNodeToNode :: ForeignPtr RedlandNode -> IO Node
redlandNodeToNode rn = do
isBlank <- nodeIsBlank rn
isLiteral <- nodeIsLiteral rn
isResource <- nodeIsResource rn
case (isBlank, isLiteral, isResource) of
(True, _, _) -> BlankNode <$> nodeGetBlankIdentifier rn
(_, True, _) -> LiteralNode <$> nodeGetLiteralValue rn
_ -> ResourceNode <$> (nodeGetURI rn >>= uriAsString)
nodeToRedlandNode :: ForeignPtr RedlandWorld
-> Node
-> Initializer RedlandNode
nodeToRedlandNode world (BlankNode s) = nodeFromBlankIdentifier world (Just s)
nodeToRedlandNode world (LiteralNode s) = nodeFromLiteral world s Nothing False
nodeToRedlandNode world (ResourceNode s) =
withNew (redlandURI world s) $ nodeFromURI world
guessingParseStringIntoModel :: ForeignPtr RedlandWorld
-> ForeignPtr RedlandModel
-> ForeignPtr RedlandURI
-> String
-> IO ()
guessingParseStringIntoModel world model uri str = do
parserName <- parserGuessName2 world Nothing (Just str) Nothing
withNew (redlandParser world parserName Nothing Nothing) $ \p ->
parseStringIntoModel p str uri model
withQuery :: ForeignPtr RedlandWorld
-> ForeignPtr RedlandModel
-> String
-> String
-> Maybe (ForeignPtr RedlandURI)
-> (QueryResults -> IO a)
-> IO a
withQuery world model ql qs bURI f =
withNew (redlandQuery world ql Nothing qs bURI) $ \query ->
withNew (modelQueryExecute model query) $ queryResultsToList >=> f
type QueryResults = [[(String, Node)]]
queryResultsToList :: ForeignPtr RedlandQueryResults -> IO QueryResults
queryResultsToList qr = do
done <- queryResultsFinished qr
if done
then pure []
else do
bindingCnt <- queryResultsGetBindingsCount qr
bindings <- mapM readBinding [0..bindingCnt - 1]
next <- queryResultsNext qr
rest <- if next then queryResultsToList qr else pure []
pure (bindings : rest)
where
readBinding :: Int -> IO (String, Node)
readBinding n = do
name <- queryResultsGetBindingName qr n
val <- queryResultsGetBindingValue qr n >>= redlandNodeToNode
pure (name, val)
data Triple = Triple { subject :: Maybe Node
, predicate :: Maybe Node
, object :: Maybe Node
} deriving (Eq, Show)
statementToTriple :: ForeignPtr RedlandStatement
-> IO Triple
statementToTriple statement = do
s <- componentToTriple statementGetSubject
p <- componentToTriple statementGetPredicate
o <- componentToTriple statementGetObject
pure $ Triple s p o
where
componentToTriple :: (ForeignPtr RedlandStatement ->
IO (Maybe (ForeignPtr RedlandNode)))
-> IO (Maybe Node)
componentToTriple f = do
c <- f statement
case c of
Just c' -> Just <$> redlandNodeToNode c'
Nothing -> pure Nothing
tripleToStatement :: ForeignPtr RedlandWorld
-> Triple
-> Initializer RedlandStatement
tripleToStatement world (Triple s p o) = do
statement <- redlandStatement world
let maybeSet f mn = case mn of
Just n -> withNew (nodeToRedlandNode world n) $ \n' ->
f statement (Just n')
Nothing -> pure ()
maybeSet statementSetSubject s
maybeSet statementSetPredicate p
maybeSet statementSetObject o
pure statement
streamToList :: ForeignPtr RedlandStream -> IO [Triple]
streamToList stream = do
done <- streamEnd stream
if done
then pure []
else do
triple <- streamGetObject stream >>= statementToTriple
next <- streamNext stream
rest <- if next then streamToList stream else pure []
pure (triple : rest)
withWSMU :: String
-> [(String, String)]
-> String
-> String
-> String
-> (ForeignPtr RedlandWorld ->
ForeignPtr RedlandStorage ->
ForeignPtr RedlandModel ->
ForeignPtr RedlandURI ->
IO a)
-> IO a
withWSMU sFactory sOpt sIdent mOpt bURI f =
withNew redlandWorld $ \world ->
withHash world "memory" sOpt $ \sOpt' ->
withNew (redlandStorageWithOptions world sFactory sIdent sOpt') $ \storage ->
withNew (redlandModel world storage mOpt) $ \model ->
withNew (redlandURI world bURI) $ \uri ->
f world storage model uri