{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Polytropos.Beam
(
BeamTable (..)
, toBeamTable
, fromBeamTable
, beamTableOfSlots
, FieldNames (..)
) where
import Data.Functor.Identity (Identity)
import Data.Kind (Type)
import Data.Proxy (Proxy (..))
import GHC.Exts (Any, toList)
import GHC.TypeLits (KnownSymbol, symbolVal)
import Database.Beam.Schema.Tables (Beamable (..), Columnar' (..), Ignored (..))
import Polytropos (Record)
import Polytropos.Core (Pair (..), Rep (..), Row, RowRep (..), RowType (..),
noInlineUnsafeCo, productRep, repVals)
class FieldNames (r :: Row) where
fieldNames :: Proxy r -> [String]
instance FieldNames '[] where
fieldNames :: Proxy '[] -> [String]
fieldNames Proxy '[]
_ = []
instance (KnownSymbol n, FieldNames r) => FieldNames ((n ':= a) ': r) where
fieldNames :: Proxy ((n ':= a) : r) -> [String]
fieldNames Proxy ((n ':= a) : r)
_ = Proxy n -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @n) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: Proxy r -> [String]
forall (r :: Row). FieldNames r => Proxy r -> [String]
fieldNames (forall (t :: Row). Proxy t
forall {k} (t :: k). Proxy t
Proxy @r)
newtype BeamTable (r :: Row) (f :: Type -> Type)
= BeamTable (RowRep f ProductRowT r ())
toBeamTable :: Record r -> BeamTable r Identity
toBeamTable :: forall (r :: Row). Record r -> BeamTable r Identity
toBeamTable (RowRep Rep Identity ()
rep) = RowRep Identity 'ProductRowT r () -> BeamTable r Identity
forall (r :: Row) (f :: * -> *).
RowRep f 'ProductRowT r () -> BeamTable r f
BeamTable (Rep Identity () -> RowRep Identity 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep Rep Identity ()
rep)
fromBeamTable :: BeamTable r Identity -> Record r
fromBeamTable :: forall (r :: Row). BeamTable r Identity -> Record r
fromBeamTable (BeamTable (RowRep Rep Identity ()
rep)) = Rep Identity () -> RowRep Identity 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep Rep Identity ()
rep
beamTableOfSlots :: [f Any] -> BeamTable r f
beamTableOfSlots :: forall (f :: * -> *) (r :: Row). [f Any] -> BeamTable r f
beamTableOfSlots [f Any]
slots = RowRep f 'ProductRowT r () -> BeamTable r f
forall (r :: Row) (f :: * -> *).
RowRep f 'ProductRowT r () -> BeamTable r f
BeamTable (Rep f () -> RowRep f 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep ([f Any] -> Rep f ()
forall {k} (f :: * -> *) (a :: k). [f Any] -> Rep f a
productRep [f Any]
slots))
instance FieldNames r => Beamable (BeamTable r) where
zipBeamFieldsM :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) (h :: * -> *).
Applicative m =>
(forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a))
-> BeamTable r f -> BeamTable r g -> m (BeamTable r h)
zipBeamFieldsM forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a)
combine (BeamTable (RowRep (Rep Word
t SmallArray (f Any)
fv))) (BeamTable (RowRep (Rep Word
_ SmallArray (g Any)
gv))) =
RowRep h 'ProductRowT r () -> BeamTable r h
forall (r :: Row) (f :: * -> *).
RowRep f 'ProductRowT r () -> BeamTable r f
BeamTable (RowRep h 'ProductRowT r () -> BeamTable r h)
-> ([h Any] -> RowRep h 'ProductRowT r ())
-> [h Any]
-> BeamTable r h
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rep h () -> RowRep h 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep (Rep h () -> RowRep h 'ProductRowT r ())
-> ([h Any] -> Rep h ()) -> [h Any] -> RowRep h 'ProductRowT r ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\[h Any]
hs -> Word -> SmallArray (h Any) -> Rep h ()
forall {k} (f :: * -> *) (a :: k).
Word -> SmallArray (f Any) -> Rep f a
Rep Word
t (Rep h (ZonkAny 2) -> SmallArray (h Any)
forall {k} (f :: * -> *) (a :: k). Rep f a -> SmallArray (f Any)
repVals ([h Any] -> Rep h (ZonkAny 2)
forall {k} (f :: * -> *) (a :: k). [f Any] -> Rep f a
productRep [h Any]
hs)))
([h Any] -> BeamTable r h) -> m [h Any] -> m (BeamTable r h)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Item (SmallArray (f Any)), Item (SmallArray (g Any)))
-> m (h Any))
-> [(Item (SmallArray (f Any)), Item (SmallArray (g Any)))]
-> m [h Any]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Item (SmallArray (f Any)), Item (SmallArray (g Any))) -> m (h Any)
step ([Item (SmallArray (f Any))]
-> [Item (SmallArray (g Any))]
-> [(Item (SmallArray (f Any)), Item (SmallArray (g Any)))]
forall a b. [a] -> [b] -> [(a, b)]
zip (SmallArray (f Any) -> [Item (SmallArray (f Any))]
forall l. IsList l => l -> [Item l]
toList SmallArray (f Any)
fv) (SmallArray (g Any) -> [Item (SmallArray (g Any))]
forall l. IsList l => l -> [Item l]
toList SmallArray (g Any)
gv))
where
step :: (Item (SmallArray (f Any)), Item (SmallArray (g Any))) -> m (h Any)
step (Item (SmallArray (f Any))
fx, Item (SmallArray (g Any))
gx) =
(Columnar' h (ZonkAny 0) -> h Any)
-> m (Columnar' h (ZonkAny 0)) -> m (h Any)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Columnar' Columnar h (ZonkAny 0)
hx) -> Columnar h (ZonkAny 0) -> h Any
forall a b. a -> b
noInlineUnsafeCo Columnar h (ZonkAny 0)
hx :: h Any)
(Columnar' f (ZonkAny 0)
-> Columnar' g (ZonkAny 0) -> m (Columnar' h (ZonkAny 0))
forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a)
combine (Item (SmallArray (f Any)) -> Columnar' f (ZonkAny 0)
forall a b. a -> b
noInlineUnsafeCo Item (SmallArray (f Any))
fx) (Item (SmallArray (g Any)) -> Columnar' g (ZonkAny 0)
forall a b. a -> b
noInlineUnsafeCo Item (SmallArray (g Any))
gx))
{-# INLINE zipBeamFieldsM #-}
tblSkeleton :: TableSkeleton (BeamTable r)
tblSkeleton =
RowRep Ignored 'ProductRowT r () -> TableSkeleton (BeamTable r)
forall (r :: Row) (f :: * -> *).
RowRep f 'ProductRowT r () -> BeamTable r f
BeamTable (Rep Ignored () -> RowRep Ignored 'ProductRowT r ()
forall {k} k1 (f :: * -> *) (r :: RowType) (row :: k1) (a :: k).
Rep f a -> RowRep f r row a
RowRep ([Ignored Any] -> Rep Ignored ()
forall {k} (f :: * -> *) (a :: k). [f Any] -> Rep f a
productRep (Int -> Ignored Any -> [Ignored Any]
forall a. Int -> a -> [a]
replicate ([String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Proxy r -> [String]
forall (r :: Row). FieldNames r => Proxy r -> [String]
fieldNames (forall (t :: Row). Proxy t
forall {k} (t :: k). Proxy t
Proxy @r))) Ignored Any
forall x. Ignored x
Ignored)))