packages feed

beam-newtype-field-0.2.0.0: src/Database/Beam/Wrapped.hs

{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances  #-}

-- | A field for dealing with newtypes, implements a bunch of default
--   db instances for them.
--   Currenlty only works with postgres
module Database.Beam.Wrapped(DBFieldWrap(..)) where

import           Control.Lens
import           Database.Beam
import           Database.Beam.Backend.SQL       (HasSqlValueSyntax (..))
import           Database.Beam.Backend.SQL.SQL92 (IsSql92DataTypeSyntax,
                                                  IsSql92ExpressionSyntax)
import           Database.Beam.Backend.Types     (BackendFromField, BeamBackend)
import           Database.Beam.Migrate
import           GHC.Generics                    (Generic)
import           Database.PostgreSQL.Simple.FromField (FromField (..))
-- | A wrapper for newtyps in the database, the only restriction it
--   places on newtypes is that they implement Wrapped from
--   Control.Lens.Wrapped.
--   The underlying types need to implmeent the various database
--   instances.
newtype DBFieldWrap a = DBFieldWrap
  { _unField :: a
  } deriving (Generic, Show)

instance Wrapped a => Wrapped (DBFieldWrap a)

instance (Wrapped a, BeamBackend be,
          FromBackendRow be (Unwrapped a),
          BackendFromField be (DBFieldWrap a)
         ) =>
         FromBackendRow be (DBFieldWrap a)

instance ( IsSql92ExpressionSyntax be
         , Wrapped a
         , HasSqlEqualityCheck be (Unwrapped a)
         ) =>
         HasSqlEqualityCheck be (DBFieldWrap a)

instance (Wrapped a, FromField (Unwrapped a)) => FromField (DBFieldWrap a) where
  fromField a b = review (_Wrapped' . _Wrapped') <$> fromField a b

instance (Wrapped a, HasSqlValueSyntax be (Unwrapped a)) =>
         HasSqlValueSyntax be (DBFieldWrap a) where
  sqlValueSyntax = sqlValueSyntax . view (_Wrapped' . _Wrapped')

instance ( IsSql92ColumnSchemaSyntax be
         , Wrapped a
         , HasDefaultSqlDataTypeConstraints be (Unwrapped a)
         ) =>
         HasDefaultSqlDataTypeConstraints be (DBFieldWrap a)

instance ( IsSql92DataTypeSyntax be
         , Wrapped a
         , HasDefaultSqlDataType be (Unwrapped a)
         ) =>
         HasDefaultSqlDataType be (DBFieldWrap a) where
  defaultSqlDataType proxy =
    defaultSqlDataType $ view (_Wrapped' . _Wrapped') <$> proxy