avers-0.0.5: src/Avers/Views.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module Avers.Views where
import Control.Monad
import Data.Text (Text)
import Data.Aeson as Aeson
import Data.Monoid
import qualified Data.HashMap.Strict as HMS
import qualified Database.RethinkDB as R
import Avers.Types
import Avers.Storage.Backend
viewTableName :: View obj a -> Text
viewTableName View{..} = "view_" <> viewName
-- | Construct the table name for the given view. The table names look
-- something like this: "view_openGames"
viewTable :: View obj a -> R.Exp R.Table
viewTable view = R.Table Nothing $ R.lift $ viewTableName view
data Record a = Record
{ recId :: ObjId
, recContent :: a
}
instance Pk (Record a) where
toPk = toPk . recId
instance (ToJSON a) => ToJSON (Record a) where
toJSON Record{..} = Aeson.Object $ HMS.insert "id" (Aeson.String $ toPk recId) hms
where (Aeson.Object hms) = toJSON recContent
instance (R.ToDatum a) => R.ToDatum (Record a) where
toDatum Record{..} = R.Object $ HMS.insert "id" (R.String $ toPk recId) $
HMS.fromList $ map (\(k,v) -> (k, R.toDatum v)) $ HMS.toList hms
where (R.Object hms) = R.toDatum recContent
updateObjectViews :: ObjectType a -> ObjId -> Maybe a -> Avers ()
updateObjectViews ObjectType{..} objId mbObj = do
forM_ otViews $ \(SomeView view) -> do
updateView view objId mbObj
updateView :: (R.ToDatum a) => View obj a -> ObjId -> Maybe obj -> Avers ()
updateView view@View{..} objId mbObj = do
case mbObj of
Nothing -> deleteDocument (viewTable view) objId
Just obj -> do
mbRecord <- viewObjectTransformer obj
case mbRecord of
Nothing -> deleteDocument (viewTable view) objId
Just rec -> upsertDocument (viewTable view) (Record objId rec)