module Polysemy.Hasql.Interpreter.Query where

import Hasql.Statement (Statement)
import Polysemy.Db.Data.DbError (DbError)
import Polysemy.Db.Effect.Query (Query (Query), query)
import Sqel.Data.Dd (Dd, DdType)
import Sqel.Data.Projection (Projection)
import Sqel.Data.QuerySchema (QuerySchema)
import Sqel.PgType (CheckedProjection, MkTableSchema, projection)
import Sqel.Query (CheckQuery, checkQuery)
import Sqel.ResultShape (ResultShape)
import Sqel.Statement (selectWhere)

import qualified Polysemy.Hasql.Effect.DbTable as DbTable
import Polysemy.Hasql.Effect.DbTable (DbTable)

interpretQuery ::
   result query proj table r .
  ResultShape proj result =>
  Member (DbTable table !! DbError) r =>
  Projection proj table ->
  QuerySchema query table ->
  InterpreterFor (Query query result !! DbError) r
interpretQuery :: forall result query proj table (r :: EffectRow).
(ResultShape proj result, Member (DbTable table !! DbError) r) =>
Projection proj table
-> QuerySchema query table
-> InterpreterFor (Query query result !! DbError) r
interpretQuery Projection proj table
proj QuerySchema query table
que =
  forall err (eff :: (* -> *) -> * -> *) (r :: EffectRow).
FirstOrder eff "interpretResumable" =>
(forall x (r0 :: EffectRow).
 eff (Sem r0) x -> Sem (Stop err : r) x)
-> InterpreterFor (Resumable err eff) r
interpretResumable \ (Query query
param) -> forall err (eff :: (* -> *) -> * -> *) (r :: EffectRow).
Members '[Resumable err eff, Stop err] r =>
InterpreterFor eff r
restop (forall a (r :: EffectRow) p o.
Member (DbTable a) r =>
p -> Statement p o -> Sem r o
DbTable.statement query
param Statement query result
stmt)
  where
    stmt :: Statement query result
    stmt :: Statement query result
stmt = forall result proj q table.
ResultShape proj result =>
QuerySchema q table -> Projection proj table -> Statement q result
selectWhere QuerySchema query table
que Projection proj table
proj

interpretQueryDd ::
   result query proj table r .
  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 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 table
table Dd proj
proj Dd query
que =
  forall result query proj table (r :: EffectRow).
(ResultShape proj result, Member (DbTable table !! DbError) r) =>
Projection proj table
-> QuerySchema query table
-> InterpreterFor (Query query result !! DbError) r
interpretQuery Projection (DdType proj) (DdType table)
ps QuerySchema (DdType query) (DdType table)
qs
  where
    qs :: QuerySchema (DdType query) (DdType table)
qs = forall (query :: DdK) (table :: DdK).
CheckQuery query table =>
Dd query -> Dd table -> QuerySchema (DdType query) (DdType table)
checkQuery Dd query
que Dd table
table
    ps :: Projection (DdType proj) (DdType table)
ps = forall (proj :: DdK) (table :: DdK).
(MkTableSchema proj, MkTableSchema table,
 CheckedProjection proj table) =>
Dd proj -> Dd table -> Projection (DdType proj) (DdType table)
projection Dd proj
proj Dd table
table

queryVia ::
  (q1 -> Sem (Stop DbError : r) q2) ->
  (r2 -> Sem (Stop DbError : r) r1) ->
  Sem (Query q1 r1 !! DbError : r) a ->
  Sem (Query q2 r2 !! DbError : r) a
queryVia :: forall q1 (r :: EffectRow) q2 r2 r1 a.
(q1 -> Sem (Stop DbError : r) q2)
-> (r2 -> Sem (Stop DbError : r) r1)
-> Sem ((Query q1 r1 !! DbError) : r) a
-> Sem ((Query q2 r2 !! DbError) : r) a
queryVia q1 -> Sem (Stop DbError : r) q2
transQ r2 -> Sem (Stop DbError : r) r1
transR =
  forall err (eff :: (* -> *) -> * -> *) (r :: EffectRow).
FirstOrder eff "interpretResumable" =>
(forall x (r0 :: EffectRow).
 eff (Sem r0) x -> Sem (Stop err : r) x)
-> InterpreterFor (Resumable err eff) r
interpretResumable \case
    Query q1
param -> do
      q2
q2 <- forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder (q1 -> Sem (Stop DbError : r) q2
transQ q1
param)
      r2
r2 <- forall err (eff :: (* -> *) -> * -> *) (r :: EffectRow).
Members '[Resumable err eff, Stop err] r =>
InterpreterFor eff r
restop (forall q o (r :: EffectRow). Member (Query q o) r => q -> Sem r o
query q2
q2)
      forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder (r2 -> Sem (Stop DbError : r) r1
transR r2
r2)
  forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder

mapQuery ::
  (q1 -> Sem (Stop DbError : r) q2) ->
  Sem (Query q1 result !! DbError : r) a ->
  Sem (Query q2 result !! DbError : r) a
mapQuery :: forall q1 (r :: EffectRow) q2 result a.
(q1 -> Sem (Stop DbError : r) q2)
-> Sem ((Query q1 result !! DbError) : r) a
-> Sem ((Query q2 result !! DbError) : r) a
mapQuery q1 -> Sem (Stop DbError : r) q2
f =
  forall q1 (r :: EffectRow) q2 r2 r1 a.
(q1 -> Sem (Stop DbError : r) q2)
-> (r2 -> Sem (Stop DbError : r) r1)
-> Sem ((Query q1 r1 !! DbError) : r) a
-> Sem ((Query q2 r2 !! DbError) : r) a
queryVia q1 -> Sem (Stop DbError : r) q2
f forall (f :: * -> *) a. Applicative f => a -> f a
pure