diff options
| author | krasimir <krasimir@chalmers.se> | 2015-09-02 07:12:36 +0000 |
|---|---|---|
| committer | krasimir <krasimir@chalmers.se> | 2015-09-02 07:12:36 +0000 |
| commit | 73b41687c8038ee69562fafd0693204509621c79 (patch) | |
| tree | 92b6253470d1a57a3409ed40015cea1446763062 /src/runtime/haskell-bind/SG.hsc | |
| parent | 4a1da62d841cb63dd4671dd3d46a4e150dd26485 (diff) | |
added the minimal Haskell API for storing expressions/triples in the semantic graph
Diffstat (limited to 'src/runtime/haskell-bind/SG.hsc')
| -rw-r--r-- | src/runtime/haskell-bind/SG.hsc | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/runtime/haskell-bind/SG.hsc b/src/runtime/haskell-bind/SG.hsc new file mode 100644 index 000000000..300cec27a --- /dev/null +++ b/src/runtime/haskell-bind/SG.hsc @@ -0,0 +1,133 @@ +{-# LANGUAGE DeriveDataTypeable #-} + +#include <pgf/pgf.h> +#include <gu/exn.h> +#include <sg/sg.h> + +module SG( SG, openSG, closeSG + , beginTrans, commit, rollback, inTransaction + , SgId + , insertExpr + , insertTriple + ) where + +import Foreign +import Foreign.C +import SG.FFI +import PGF2.FFI +import PGF2.Expr + +import Data.Typeable +import Control.Exception(Exception,SomeException,catch,throwIO) + +----------------------------------------------------------------------- +-- Global database operations and types + +newtype SG = SG {sg :: Ptr SgSG} + +openSG :: FilePath -> IO SG +openSG fpath = + withCString fpath $ \c_fpath -> + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + sg <- sg_open c_fpath exn + failed <- gu_exn_is_raised exn + if failed + then do is_errno <- gu_exn_caught exn gu_exn_type_GuErrno + if is_errno + then do perrno <- (#peek GuExn, data.data) exn + errno <- peek perrno + ioError (errnoToIOError "openSG" (Errno errno) Nothing (Just fpath)) + else do is_sgerr <- gu_exn_caught exn gu_exn_type_SgError + if is_sgerr + then do c_msg <- (#peek GuExn, data.data) exn + msg <- peekCString c_msg + throwIO (SGError msg) + else throwIO (SGError "The database cannot be opened") + else return (SG sg) + +closeSG :: SG -> IO () +closeSG (SG sg) = + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + sg <- sg_close sg exn + handle_sg_exn exn + +beginTrans :: SG -> IO () +beginTrans (SG sg) = + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + sg <- sg_begin_trans sg exn + handle_sg_exn exn + +commit :: SG -> IO () +commit (SG sg) = + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + sg <- sg_commit sg exn + handle_sg_exn exn + +rollback :: SG -> IO () +rollback (SG sg) = + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + sg <- sg_rollback sg exn + handle_sg_exn exn + +inTransaction :: SG -> IO a -> IO a +inTransaction sg f = + catch (beginTrans sg >> f >>= \x -> commit sg >> return x) + (\e -> rollback sg >> throwIO (e :: SomeException)) + +----------------------------------------------------------------------- +-- Expressions + +insertExpr :: SG -> Expr -> IO SgId +insertExpr (SG sg) (Expr expr _) = + withGuPool $ \tmpPl -> do + exn <- gu_new_exn tmpPl + id <- sg_insert_expr sg expr exn + handle_sg_exn exn + return id + +----------------------------------------------------------------------- +-- Triples + +insertTriple :: SG -> Expr -> Expr -> Expr -> IO SgId +insertTriple (SG sg) (Expr expr1 _) (Expr expr2 _) (Expr expr3 _) = + withGuPool $ \tmpPl -> + withTriple $ \triple -> do + exn <- gu_new_exn tmpPl + id1 <- sg_insert_expr sg expr1 exn + handle_sg_exn exn + pokeElemOff triple 0 id1 + id2 <- sg_insert_expr sg expr2 exn + handle_sg_exn exn + pokeElemOff triple 1 id2 + id3 <- sg_insert_expr sg expr3 exn + handle_sg_exn exn + pokeElemOff triple 2 id3 + id <- sg_insert_triple sg triple exn + handle_sg_exn exn + return id + +----------------------------------------------------------------------- +-- Exceptions + +newtype SGError = SGError String + deriving (Show, Typeable) + +instance Exception SGError + +handle_sg_exn exn = do + failed <- gu_exn_is_raised exn + if failed + then do is_sgerr <- gu_exn_caught exn gu_exn_type_SgError + if is_sgerr + then do c_msg <- (#peek GuExn, data.data) exn + msg <- peekCString c_msg + throwIO (SGError msg) + else throwIO (SGError "Unknown database error") + else return () + +----------------------------------------------------------------------- |
