-- | Description: PostgreSQL interpreters for the query for an account by name
module Polysemy.Account.Db.Interpreter.AccountByName where

import Data.UUID (UUID)
import Polysemy.Db (DbError)
import Polysemy.Db (InitDbError)
import Polysemy.Db.Ext (Query (..))
import Polysemy.Hasql (interpretQueryDd)
import Polysemy.Hasql (DbTable)
import Sqel (CheckedProjection, Dd, FullCodec, Uuid, primNewtype, prod)
import Sqel.Ext (Column, ReifyCodec, ReifyDd)

import Polysemy.Account.Data.Account (Account, AccountP)
import Polysemy.Account.Data.AccountByName (AccountByName)
import Polysemy.Account.Db.Dd (DdAccount, account, accountP)

-- | Interpret @'Query' 'AccountByName'@ with [Polysemy.Hasql]("Polysemy.Hasql").
interpretQueryAccountByNameDb ::
   p s r .
  Column p "privileges" s s =>
  ReifyCodec FullCodec s p =>
  ReifyDd s =>
  CheckedProjection (DdAccount UUID p s) (DdAccount UUID p s) =>
  Members [DbTable (Uuid (Account p)) !! DbError, Error InitDbError] r =>
  Dd s ->
  InterpreterFor (Query AccountByName (Maybe (Uuid (Account p))) !! DbError) r
interpretQueryAccountByNameDb :: forall p (s :: DdK) (r :: EffectRow).
(Column p "privileges" s s, ReifyCodec FullCodec s p, ReifyDd s,
 CheckedProjection (DdAccount UUID p s) (DdAccount UUID p s),
 Members
   '[DbTable (Uuid (Account p)) !! DbError, Error InitDbError] r) =>
Dd s
-> InterpreterFor
     (Query AccountByName (Maybe (Uuid (Account p))) !! DbError) r
interpretQueryAccountByNameDb Dd s
p =
  forall result (query :: DdK) (proj :: DdK) (table :: DdK)
       (r :: EffectRow).
(MkTableSchema proj, MkTableSchema table,
 CheckedProjection proj table, CheckQuery query table,
 ResultShape (DdType proj) result,
 Member (DbTable (DdType table) !! DbError) r) =>
Dd table
-> Dd proj
-> Dd query
-> InterpreterFor (Query (DdType query) result !! DbError) r
interpretQueryDd Dd (DdAccount UUID p s)
table Dd (DdAccount UUID p s)
table Dd
  ('DdK
     'SelAuto
     '[]
     AccountByName
     ('Comp
        ('TSel 'DefaultPrefix "AccountByName")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK
             ('SelSymbol "name")
             '[Newtype AccountName Text]
             AccountName
             'Prim]))
query
  where
    table :: Dd (DdAccount UUID p s)
table = forall p (s :: DdK) i.
Column p "privileges" s s =>
Dd s -> Dd (DdAccount i p s)
account Dd s
p
    query :: Dd
  ('DdK
     'SelAuto
     '[]
     AccountByName
     ('Comp
        ('TSel 'DefaultPrefix "AccountByName")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK
             ('SelSymbol "name")
             '[Newtype AccountName Text]
             AccountName
             'Prim]))
query = forall a arg (s :: DdK). Product a arg s => arg -> Dd s
prod forall a w (err :: ErrorMessage).
(err ~ NewtypeError, UnwrapNewtype err a w) =>
Dd ('DdK 'SelAuto '[Newtype a w] a 'Prim)
primNewtype

-- | Interpret @'Query' 'AccountByName'@ with [Polysemy.Hasql]("Polysemy.Hasql").
--
-- Convenience specialization for the default privilege type.
interpretQueryAccountPByNameDb ::
  Members [DbTable (Uuid AccountP) !! DbError, Error InitDbError] r =>
  InterpreterFor (Query AccountByName (Maybe (Uuid AccountP)) !! DbError) r
interpretQueryAccountPByNameDb :: forall (r :: EffectRow).
Members
  '[DbTable (Uuid AccountP) !! DbError, Error InitDbError] r =>
InterpreterFor
  (Query AccountByName (Maybe (Uuid AccountP)) !! DbError) r
interpretQueryAccountPByNameDb =
  forall result (query :: DdK) (proj :: DdK) (table :: DdK)
       (r :: EffectRow).
(MkTableSchema proj, MkTableSchema table,
 CheckedProjection proj table, CheckQuery query table,
 ResultShape (DdType proj) result,
 Member (DbTable (DdType table) !! DbError) r) =>
Dd table
-> Dd proj
-> Dd query
-> InterpreterFor (Query (DdType query) result !! DbError) r
interpretQueryDd forall {i}.
Dd
  ('DdK
     'SelAuto
     '[]
     (Uid i AccountP)
     ('Comp
        ('TSel 'DefaultPrefix "Account")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK ('SelSymbol "id") '[PrimaryKey] i 'Prim,
           'DdK
             'SelAuto
             '[]
             AccountP
             ('Comp
                ('TSel 'DefaultPrefix "Account")
                ('Prod 'Reg)
                'Merge
                '[ 'DdK
                     ('SelSymbol "name") '[Newtype AccountName Text] AccountName 'Prim,
                   'DdK
                     ('SelSymbol "status")
                     '[PgPrimName, EnumColumn]
                     AccountStatus
                     'Prim,
                   'DdK
                     ('SelSymbol "privileges")
                     '[ArrayColumn [], PgPrimName, EnumColumn]
                     [Privilege]
                     'Prim])]))
table forall {i}.
Dd
  ('DdK
     'SelAuto
     '[]
     (Uid i AccountP)
     ('Comp
        ('TSel 'DefaultPrefix "Account")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK ('SelSymbol "id") '[PrimaryKey] i 'Prim,
           'DdK
             'SelAuto
             '[]
             AccountP
             ('Comp
                ('TSel 'DefaultPrefix "Account")
                ('Prod 'Reg)
                'Merge
                '[ 'DdK
                     ('SelSymbol "name") '[Newtype AccountName Text] AccountName 'Prim,
                   'DdK
                     ('SelSymbol "status")
                     '[PgPrimName, EnumColumn]
                     AccountStatus
                     'Prim,
                   'DdK
                     ('SelSymbol "privileges")
                     '[ArrayColumn [], PgPrimName, EnumColumn]
                     [Privilege]
                     'Prim])]))
table Dd
  ('DdK
     'SelAuto
     '[]
     AccountByName
     ('Comp
        ('TSel 'DefaultPrefix "AccountByName")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK
             ('SelSymbol "name")
             '[Newtype AccountName Text]
             AccountName
             'Prim]))
query
  where
    table :: Dd
  ('DdK
     'SelAuto
     '[]
     (Uid i AccountP)
     ('Comp
        ('TSel 'DefaultPrefix "Account")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK ('SelSymbol "id") '[PrimaryKey] i 'Prim,
           'DdK
             'SelAuto
             '[]
             AccountP
             ('Comp
                ('TSel 'DefaultPrefix "Account")
                ('Prod 'Reg)
                'Merge
                '[ 'DdK
                     ('SelSymbol "name") '[Newtype AccountName Text] AccountName 'Prim,
                   'DdK
                     ('SelSymbol "status")
                     '[PgPrimName, EnumColumn]
                     AccountStatus
                     'Prim,
                   'DdK
                     ('SelSymbol "privileges")
                     '[ArrayColumn [], PgPrimName, EnumColumn]
                     [Privilege]
                     'Prim])]))
table = forall {i}.
Dd
  ('DdK
     'SelAuto
     '[]
     (Uid i AccountP)
     ('Comp
        ('TSel 'DefaultPrefix "Account")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK ('SelSymbol "id") '[PrimaryKey] i 'Prim,
           'DdK
             'SelAuto
             '[]
             AccountP
             ('Comp
                ('TSel 'DefaultPrefix "Account")
                ('Prod 'Reg)
                'Merge
                '[ 'DdK
                     ('SelSymbol "name") '[Newtype AccountName Text] AccountName 'Prim,
                   'DdK
                     ('SelSymbol "status")
                     '[PgPrimName, EnumColumn]
                     AccountStatus
                     'Prim,
                   'DdK
                     ('SelSymbol "privileges")
                     '[ArrayColumn [], PgPrimName, EnumColumn]
                     [Privilege]
                     'Prim])]))
accountP
    query :: Dd
  ('DdK
     'SelAuto
     '[]
     AccountByName
     ('Comp
        ('TSel 'DefaultPrefix "AccountByName")
        ('Prod 'Reg)
        'Nest
        '[ 'DdK
             ('SelSymbol "name")
             '[Newtype AccountName Text]
             AccountName
             'Prim]))
query = forall a arg (s :: DdK). Product a arg s => arg -> Dd s
prod forall a w (err :: ErrorMessage).
(err ~ NewtypeError, UnwrapNewtype err a w) =>
Dd ('DdK 'SelAuto '[Newtype a w] a 'Prim)
primNewtype