summaryrefslogtreecommitdiff
path: root/com/influencedbybooks/keep.hs
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2019-10-27 09:48:52 -0700
committerBen Sima <ben@bsima.me>2019-10-27 12:14:40 -0700
commitc790672cc244ac4caba1bda3572829a6c6862891 (patch)
tree2706bb8044f7b14840c5f90f215b79b433e81045 /com/influencedbybooks/keep.hs
parent44df4ba39f65c3afd84bee6b03f47d9b061e9038 (diff)
move everything to namespace directories
Diffstat (limited to 'com/influencedbybooks/keep.hs')
-rw-r--r--com/influencedbybooks/keep.hs124
1 files changed, 124 insertions, 0 deletions
diff --git a/com/influencedbybooks/keep.hs b/com/influencedbybooks/keep.hs
new file mode 100644
index 0000000..0bc527a
--- /dev/null
+++ b/com/influencedbybooks/keep.hs
@@ -0,0 +1,124 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+-- | Keep is a database built on Data.Acid.
+--
+-- If this proves useful, maybe we could make it a more general thing. Like
+-- `Biz.Keep`. I could wrap all the safecopy stuff in my own template haskell
+-- like `$(keep ''MyType)`.
+--
+module Com.InfluencedByBooks.Keep where
+
+import Com.InfluencedByBooks.Core (Person(..), Book(..))
+import Control.Monad.State (get, put)
+import Control.Monad.Reader (ask)
+import Data.Acid (Update, makeAcidic)
+import qualified Data.Acid as Acid
+import Data.Data (Data, Typeable)
+import Data.IxSet (Indexable(..), IxSet, ixFun, ixSet)
+import qualified Data.IxSet as IxSet
+import Data.SafeCopy
+import Data.Text (Text)
+import qualified Data.Text as Text
+
+import qualified Com.InfluencedByBooks.Influencers as Influencers
+
+-- * Keep
+
+-- | Main database. Need to think of a better name for this.
+data IbbKeep = IbbKeep
+ { _people :: IxSet Person
+ }
+ deriving (Data, Typeable)
+
+$(deriveSafeCopy 0 'base ''IbbKeep)
+
+-- * Index @Person@
+
+$(deriveSafeCopy 0 'base ''Person)
+
+newtype PersonName =
+ PersonName Text deriving (Eq, Ord, Data, Typeable)
+
+newtype PersonBlurb =
+ PersonBlurb Text deriving (Eq, Ord, Data, Typeable)
+
+instance Indexable Person where
+ empty = ixSet
+ [ ixFun $ \p -> [ PersonName $ _name p ]
+ , ixFun $ \p -> [ _pic p ]
+ , ixFun $ \p -> [ _twitter p ]
+ , ixFun $ \p -> [ _website p ]
+ , ixFun $ \p -> [ _books p ]
+ , ixFun $ \p -> [ PersonBlurb $ _blurb p ]
+ ]
+
+-- | updates the `IbbKeep` with a new `Person`
+newPerson :: Text -> Text -> Update IbbKeep Person
+newPerson name blurb = do
+ k <- get
+ put $ k { _people = IxSet.insert p (_people k)
+ }
+ return p
+ where
+ p = Person
+ { _name = name
+ , _pic = Text.empty
+ , _twitter = Text.empty
+ , _website = Text.empty
+ , _books = []
+ , _blurb = blurb
+ }
+
+getPeople :: Int -> Acid.Query IbbKeep [Person]
+getPeople n = do
+ keep <- ask
+ return $ take n $ IxSet.toList $ _people keep
+
+-- * Index @Book@
+
+$(deriveSafeCopy 0 'base ''Book)
+
+newtype BookTitle =
+ BookTitle Text deriving (Eq, Ord, Data, Typeable)
+
+newtype BookAuthor =
+ BookAuthor Text deriving (Eq, Ord, Data, Typeable)
+
+instance Indexable Book where
+ empty = ixSet
+ [ ixFun $ \b -> [ BookTitle $ _title b ]
+ , ixFun $ \b -> [ BookAuthor $ _author b ]
+ , ixFun $ \b -> [ _amznref b ]
+ ]
+
+-- | updates the `IbbKeep` with a new `Book`
+--newBook :: Text -> Text -> Text -> Update IbbKeep Book
+--newBook title author amznref = do
+-- ibbKeep <- get
+-- put $ ibbKeep { _books = IxSet.insert b (_books ibbKeep)
+-- , _people = _people ibbKeep
+-- }
+-- return b
+-- where
+-- b = Book { _title = title
+-- , _author = author
+-- , _amznref = amznref
+-- }
+
+-- * Opening the keep
+
+-- defines @NewPerson@ for us.
+$(makeAcidic ''IbbKeep ['newPerson, 'getPeople])
+
+initialIbbKeep :: IbbKeep
+initialIbbKeep = IbbKeep
+ { _people = IxSet.fromList Influencers.allPeople
+ }
+
+openLocal :: String -> IO (Acid.AcidState IbbKeep)
+openLocal dir =
+ Acid.openLocalStateFrom dir initialIbbKeep