packages feed

wakame-0.1.0.0: test/examples/Wakame/Examples/Usage.hs

{-# LANGUAGE AllowAmbiguousTypes   #-}
{-# LANGUAGE DuplicateRecordFields #-}
module Wakame.Examples.Usage where

import Prelude

import Data.Text (Text)
import Data.Time (UTCTime, getCurrentTime)
import GHC.Generics
import Wakame


newtype ID a = ID Int
  deriving (Eq, Show, Generic)

data User =
  User
  { id         :: ID User
  , email      :: Text
  , username   :: Text
  , created_at :: UTCTime
  , updated_at :: UTCTime
  }
  deriving (Show, Generic)

data UpdatingUser =
  UpdatingUser
  { email    :: Text
  , username :: Text
  }
  deriving (Show, Generic)

updateUser :: UpdatingUser -> User -> User
updateUser updating user = fromRow $ nub $ union (toRow updating) (toRow user)

touchUser :: UTCTime -> User -> User
touchUser time user = fromRow $ nub $ union (toRow $ keyed @"updated_at" time) (toRow user)

updateAndTouchUser :: UpdatingUser -> UTCTime -> User -> User
updateAndTouchUser updating time user =
  fromRow $ nub $ union (toRow updating) $ union (toRow $ keyed @"updated_at" time) (toRow user)


data ModelBase a =
  ModelBase
  { id         :: ID a
  , created_at :: UTCTime
  , updated_at :: UTCTime
  }
  deriving (Eq, Show, Generic)

create ::
  forall a b.
  ( IsRow a
  , IsRow b
  , Lacks "id" (Of a)
  , Merge (Of a) (Of (ModelBase b)) (Of b)
  ) => a -> IO b
create x = do
  now <- getCurrentTime
  id' <- pure $ ID @b 42 -- shall be `getNextID` or something in practice.
  let y =
        fromRow
        $ merge (toRow x)
        $ toRow $ ModelBase @b id' now now
  pure y

type OfUpdatedAt = '[ '("updated_at", UTCTime) ]
update ::
  ( IsRow a
  , IsRow b
  , Union (Of a) (Of b) ab
  , Merge OfUpdatedAt ab (Of b)
  ) => a -> b -> IO b
update updating x = do
  now <- getCurrentTime
  let y =
        fromRow
        $ merge (toRow $ keyed @"updated_at" now)
        $ union (toRow updating)
        $ toRow x
  pure y