hypher-0.1.0: src/Database/Neo4j/Property.hs
{-# LANGUAGE OverloadedStrings #-}
module Database.Neo4j.Property where
import Control.Exception.Lifted (throw, catch)
import qualified Data.Aeson as J
import qualified Data.HashMap.Lazy as M
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Database.Neo4j.Types
import Database.Neo4j.Http
-- | Retrieve relationship/node properties from the DB, if the entity is not present it will raise an exception
-- If the entity doesn't exist it will raise a Neo4jNoEntity exception
getProperties :: Entity a => a -> Neo4j Properties
getProperties e = Neo4j $ \conn -> httpRetrieveSure conn (propertyPath e) `catch` proc404Exc e
-- | Get a relationship/node property
-- If the 404 is because the parent entity doesn't exist we'll raise the corresponding Neo4jNoEntity
-- If the 404 is because there is no property just return Nothing
getProperty :: Entity a => a -> T.Text -> Neo4j (Maybe PropertyValue)
getProperty e prop = Neo4j $ \conn -> do
res <- httpRetrieveValue conn path
case res of
Right value -> return value
Left expl -> if expl `elem` excList then throw (Neo4jNoEntityException $ entityPath e)
else return Nothing
where path = propertyPath e <> "/" <> TE.encodeUtf8 prop
excList = ["RelationshipNotFoundException", "NodeNotFoundException"]
-- | Set all relationship/node properties
-- If the entity doesn't exist it will raise a Neo4jNoEntity exception
setProperties :: Entity a => a -> Properties -> Neo4j a
setProperties e props = Neo4j $ \conn -> (do
httpModify conn (propertyPath e) $ J.encode props
return $ setEntityProperties e props) `catch` proc404Exc e
-- | Set a relationship/node property
-- If the entity doesn't exist it will raise a Neo4jNoEntity exception
setProperty :: Entity a => a -> T.Text -> PropertyValue -> Neo4j a
setProperty e name value = Neo4j $ \conn -> (do
httpModify conn (propertyPath e <> "/" <> TE.encodeUtf8 name) $ J.encode value
return $ setEntityProperties e $ M.insert name value (getEntityProperties e)) `catch` proc404Exc e
-- | Delete all relationship/node properties
-- If the entity doesn't exist it will raise a Neo4jNoEntity exception
deleteProperties :: Entity a => a -> Neo4j a
deleteProperties e = Neo4j $ \conn -> (do
httpDeleteNo404 conn (propertyPath e)
return $ setEntityProperties e emptyProperties) `catch` proc404Exc e
-- | Delete a relationship/node property
-- If the entity doesn't exist it will raise a Neo4jNoEntity exception
deleteProperty :: Entity a => a -> T.Text -> Neo4j a
deleteProperty e name = Neo4j $ \conn -> do
res <- httpDelete404Explained conn (propertyPath e <> "/" <> TE.encodeUtf8 name)
case res of
Right _ -> return resultingProps
Left expl -> if expl `elem` excList then throw (Neo4jNoEntityException $ entityPath e)
else return resultingProps
where excList = ["RelationshipNotFoundException", "NodeNotFoundException"]
resultingProps = setEntityProperties e $ M.delete name (getEntityProperties e)