tripLL (empty) → 0.1.0.0
raw patch · 6 files changed
+307/−0 lines, 6 filesdep +basedep +bytestringdep +cerealsetup-changed
Dependencies added: base, bytestring, cereal, filepath, leveldb-haskell
Files
- LICENSE +20/−0
- README.md +35/−0
- Setup.hs +2/−0
- src/TripLL.hs +72/−0
- src/TripLL/Bindings/LevelDBHexa.hs +144/−0
- tripLL.cabal +34/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Philipp Pfeiffer++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,35 @@+# tripLL++## Introduction++`tripLL` is a very simple triple store, written in Haskell. It provides a basic interface to write, delete and query triples -- in fact, that's it. On top, there are some bindings to realizations of triple stores, such that this tiny library can be used out of box.++Right now it is thought that exactly one binding is imported within a project and only this binding (since it re-exports the interface).++## A simple example++```{.Haskell}+{-# LANGUAGE OverloadedStrings #-}++{- This examples uses the leveldb realization. This means that triples become triples of strict bytestrings and the leveldb lib has to be installed. -}++import TripLL.Bindings.LevelDBHexa++main = do -- open the database:+ handle <- createAndOpen "data/store.tripdb" :: IO LevelDBHexa+ -- batch something into it:+ batch [ Put (Triple "Frenzy" "likes" "Jealousy")+ , Put (Triple "Hate" "loves" "Hatred")+ , Put (Triple "Frenzy" "likes" "Hate")]+ handle+ -- querying the database:+ res <- query (Triple (Just "Frenzy") Nothing Nothing) handle+ -- now, `res :: [Triple Strict.ByteString]`, do something with it...+ -- ...+ -- and clean up:+ close handle+```++## Contributions++The LevelDB Binding is based upon (http://nodejsconfit.levelgraph.io/), which is based upon the idea to build up a hexastore. Freely interpreted.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/TripLL.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE OverloadedStrings, MultiParamTypeClasses, FunctionalDependencies #-}+{-|+Module : TripLL+Description : The tripLL interface.+Copyright : (c) Philipp Pfeiffer, 2015+License : MIT+Maintainer : pfiff@hax-f.net+Stability : experimental+Portability : POSIX++Gives a basic interface to a triple store. See homepage for an example.+-}+module TripLL (+ -- * Base Types for Accesing and Querying+ Triplestore (..),+ Triple (..),+ TriplePosition (..),+ flatten,+ QueryTriple (..),+ BatchAction (..)+) where++----- System: -----+import System.FilePath++-- | The 'Triplestore' typeclass is an interface for triple stores. Every backend of this library uses this interface.+class Triplestore h b | h -> b where+ -- | most simple actions, a triple store has to support, 'put' and 'del' of triples:+ put :: Triple b -> h -> IO ()+ del :: Triple b -> h -> IO ()+ -- | doing several simple actions in one go, one can use 'batch'.+ batch :: [BatchAction b] -> h -> IO ()+ -- | querying triples is done by filling in the known fields with 'Just x'.+ query :: QueryTriple b -> h -> IO [Triple b]+ -- bracket:+ withTrip :: FilePath -> (h -> IO a) -> IO a+ -- system:+ createAndOpen :: FilePath -> IO h+ open :: FilePath -> IO h+ close :: h -> IO ()+++-- | 'TriplePosition' gives a type for the fields within a 'Triple'.+data TriplePosition = Subject | Predicate | Object deriving (Eq, Show)++-- | A 'Triple' is just anything consisting of three ordered pieces.+data Triple a = Triple { subject :: a+ , predicate :: a+ , object :: a }++-- | 'QueryTriple' is a shorthand for 'Triple' where the argument is encapsulated within a 'Maybe'.+type QueryTriple a = Triple (Maybe a)+++-- | With 'within' one can query accessor invariant the different elements of a triple. Meant to be used in infix: @Subject `within` (Triple "s" "p" "o") == "s"@.+within :: TriplePosition -> Triple a -> a+within Subject = subject+within Predicate = predicate+within Object = object++-- | 'into' can be used as a annotated setter.+into :: Triple a -> TriplePosition -> a -> Triple a+into t Subject x = t { subject = x }+into t Predicate x = t { predicate = x }+into t Object x = t { object = x }++-- | 'flatten' forgets about the description of the fields.+flatten :: Triple a -> (a, a, a)+flatten (Triple s p o) = (s,p,o)++-- | A 'BatchAction' is either a 'Put' or a 'Delete', i.e. either a `write given triple into database` or a `delete given triple from database`.+data BatchAction a = Put (Triple a) | Delete (Triple a)
+ src/TripLL/Bindings/LevelDBHexa.hs view
@@ -0,0 +1,144 @@+{-# LANGUAGE TypeSynonymInstances+ , OverloadedStrings+ , MultiParamTypeClasses+ , FlexibleInstances #-}+{-|+Module : TripLL.Bindings.LevelDBHexa+Description : An implementation for the tripLL interface.+Copyright : (c) Philipp Pfeiffer, 2015+License : MIT+Maintainer : pfiff@hax-f.net+Stability : experimental+Portability : POSIX++Gives an implementation for the tripLL interface based upon the `LevelDB` database.+-}+module TripLL.Bindings.LevelDBHexa (++ -- * Base Types+ LevelDBHexa (..),+ -- Re-Exports:+ module TripLL+) where++---- LevelDB: ----+import qualified Database.LevelDB.Base as LDB+import qualified Database.LevelDB.Streaming as S+import qualified Database.LevelDB.Internal as LDBI+---- Intern: ----+import TripLL+---- Data: ----+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as LS+import qualified Data.Serialize as BIN+import Data.Either (rights)+---- Control: ----+import Control.Applicative+import Control.Monad++++-------------+-- Base Types+-------------+-- | The main handle of this implementation, 'LevelDBHexa'.+type LevelDBHexa = LDB.DB+type ByTriple = Triple BS.ByteString+type QueryByTriple = QueryTriple BS.ByteString+++-------------------+-- Encoding:+-------------------+instance BIN.Serialize ByTriple where+ put (Triple s p o) = BIN.put (s,p,o)+ get = fmap (\(s,p,o) -> Triple s p o) BIN.get+++----------------+-- Intern Misc+----------------+tupleKey :: BS.ByteString -> BS.ByteString -> BS.ByteString -> BS.ByteString -> BS.ByteString+tupleKey i v1 v2 v3 = i+ `BS.append` "::"+ `BS.append` v1+ `BS.append` "::"+ `BS.append` v2+ `BS.append` "::"+ `BS.append` v3+++queryOpener :: Maybe BS.ByteString -> Maybe BS.ByteString -> Maybe BS.ByteString -> BS.ByteString+queryOpener Nothing Nothing Nothing = "spo::"+queryOpener (Just s) Nothing Nothing = "spo::" `BS.append` s+queryOpener Nothing (Just p) Nothing = "pso::" `BS.append` p+queryOpener Nothing Nothing (Just o) = "ops::" `BS.append` o+queryOpener (Just s) (Just p) Nothing = "spo::" `BS.append` s `BS.append` "::" `BS.append` p+queryOpener (Just s) Nothing (Just o) = "osp::" `BS.append` o `BS.append` "::" `BS.append` s+queryOpener Nothing (Just p) (Just o) = "ops::" `BS.append` o `BS.append` "::" `BS.append` p+queryOpener (Just s) (Just p) (Just o) = "spo::" `BS.append` s `BS.append` "::" `BS.append` p `BS.append` "::" `BS.append` o+++---------------------+-- Hexastore Instance+---------------------+instance Triplestore LevelDBHexa BS.ByteString where+ -------------------+ -- PUT into+ -------------------+ put (Triple s p o) db = let+ encodedTrip = BIN.encode (Triple s p o)+ in+ LDB.write db LDB.defaultWriteOptions+ [ LDB.Put (tupleKey "spo" s p o) encodedTrip+ --, LDB.Put (tupleKey "sop" s o p) encodedTrip+ , LDB.Put (tupleKey "pso" p s o) encodedTrip+ --, LDB.Put (tupleKey "pos" p o s) encodedTrip+ , LDB.Put (tupleKey "osp" o s p) encodedTrip+ , LDB.Put (tupleKey "ops" o p s) encodedTrip ]++ -------------------+ -- DELETE+ -------------------+ del (Triple s p o) db = LDB.write db LDB.defaultWriteOptions+ [ LDB.Del (tupleKey "spo" s p o)+ --, LDB.Del (tupleKey "sop" s o p)+ , LDB.Del (tupleKey "pso" p s o)+ --, LDB.Del (tupleKey "pos" p o s)+ , LDB.Del (tupleKey "osp" o s p)+ , LDB.Del (tupleKey "ops" o p s) ]++ -----------------------+ -- BATCH operations+ -----------------------+ batch [] _ = return ()+ batch (Put t:xs) db = do { TripLL.put t db; batch xs db }+ batch (Delete t:xs) db = do { TripLL.del t db; batch xs db }++ ----------------------+ -- QUERY+ ----------------------+ query (Triple s p o) db =+ let+ op = queryOpener s p o+ in+ LDB.withIter db LDB.defaultReadOptions $ \iter ->+ do+ entries <- S.toList $ S.entrySlice iter+ (S.KeyRange+ op+ (\bs -> compare bs (op `BS.append` "\xff")))+ S.Asc+ return $ rights (fmap (BIN.decode . snd) entries)++ --------------------------+ -- WITHHEXA bracket+ --------------------------+ withTrip path = LDB.withDB path (LDB.defaultOptions { LDB.createIfMissing = False, LDB.errorIfExists = False })++ -------------------------+ -- CREATE+ -------------------------+ createAndOpen path = LDB.open path (LDB.defaultOptions { LDB.createIfMissing = True, LDB.errorIfExists = True })+ open path = LDB.open path (LDB.defaultOptions { LDB.createIfMissing = False, LDB.errorIfExists = False})+ close = LDBI.unsafeClose
+ tripLL.cabal view
@@ -0,0 +1,34 @@+-- Initial tripLL.cabal generated by cabal init. For further+-- documentation, see http://haskell.org/cabal/users-guide/++name: tripLL+version: 0.1.0.0+synopsis: A very simple triple store+-- description:+homepage: https://github.com/aphorisme/tripLL+license: MIT+license-file: LICENSE+author: Philipp Pfeiffer+maintainer: pfiff@hax-f.net+-- copyright:+category: Database+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ exposed-modules: TripLL+ , TripLL.Bindings.LevelDBHexa+ -- other-modules:+ other-extensions: OverloadedStrings+ , MultiParamTypeClasses+ , FunctionalDependencies+ , TypeSynonymInstances+ , FlexibleInstances+ build-depends: base >=4.8 && <4.9+ , filepath >=1.4 && <1.5+ , bytestring >=0.10 && <0.11+ , cereal >= 0.4+ , leveldb-haskell >= 0.6+ hs-source-dirs: src+ default-language: Haskell2010