module Conduit.Features.Articles.Common.QueryFavStats where

import Conduit.DB.Core (id2sqlKey)
import Conduit.DB.Utils (suchThat)
import Conduit.Features.Account.Types (UserID)
import Conduit.Features.Articles.DB (Article, Favorite)
import Database.Esqueleto.Experimental (Entity, SqlExpr, Value, exists, from, just, subSelectCount, table, val, (&&.), (==.))

queryFavStats :: Maybe UserID -> SqlExpr (Entity Article) -> (SqlExpr (Value Bool), SqlExpr (Value Int))
queryFavStats :: Maybe UserID
-> SqlExpr (Entity Article)
-> (SqlExpr (Value Bool), SqlExpr (Value Int))
queryFavStats Maybe UserID
userID SqlExpr (Entity Article)
a = (SqlExpr (Value Bool)
favorited, SqlExpr (Value Int)
numFavs)
  where
    favorited :: SqlExpr (Value Bool)
favorited = SqlQuery () -> SqlExpr (Value Bool)
exists (SqlQuery () -> SqlExpr (Value Bool))
-> SqlQuery () -> SqlExpr (Value Bool)
forall a b. (a -> b) -> a -> b
$ SqlQuery (SqlExpr (Entity Favorite)) -> SqlQuery ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (SqlQuery (SqlExpr (Entity Favorite)) -> SqlQuery ())
-> SqlQuery (SqlExpr (Entity Favorite)) -> SqlQuery ()
forall a b. (a -> b) -> a -> b
$ From (SqlExpr (Entity Favorite))
-> SqlQuery (SqlExpr (Entity Favorite))
forall a a'. ToFrom a a' => a -> SqlQuery a'
from (forall ent. PersistEntity ent => From (SqlExpr (Entity ent))
table @Favorite)
      SqlQuery (SqlExpr (Entity Favorite))
-> (SqlExpr (Entity Favorite) -> SqlExpr (Value Bool))
-> SqlQuery (SqlExpr (Entity Favorite))
forall a. SqlQuery a -> (a -> SqlExpr (Value Bool)) -> SqlQuery a
`suchThat` \SqlExpr (Entity Favorite)
f' ->
        (SqlExpr (Entity Article)
a.id SqlExpr (Value (Key Article))
-> SqlExpr (Value (Key Article)) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
==. SqlExpr (Entity Favorite)
f'.article) SqlExpr (Value Bool)
-> SqlExpr (Value Bool) -> SqlExpr (Value Bool)
&&. (SqlExpr (Value (Key User)) -> SqlExpr (Value (Maybe (Key User)))
forall typ. SqlExpr (Value typ) -> SqlExpr (Value (Maybe typ))
just SqlExpr (Entity Favorite)
f'.user SqlExpr (Value (Maybe (Key User)))
-> SqlExpr (Value (Maybe (Key User))) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
==. Maybe (Key User) -> SqlExpr (Value (Maybe (Key User)))
forall typ. PersistField typ => typ -> SqlExpr (Value typ)
val (Maybe UserID
userID Maybe UserID -> (UserID -> Key User) -> Maybe (Key User)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> UserID -> Key User
forall t id. SqlKey t id => id -> Key t
id2sqlKey))

    numFavs :: SqlExpr (Value Int)
numFavs = forall a ignored.
(Num a, PersistField a) =>
SqlQuery ignored -> SqlExpr (Value a)
subSelectCount @Int (SqlQuery (SqlExpr (Entity Favorite)) -> SqlExpr (Value Int))
-> SqlQuery (SqlExpr (Entity Favorite)) -> SqlExpr (Value Int)
forall a b. (a -> b) -> a -> b
$ From (SqlExpr (Entity Favorite))
-> SqlQuery (SqlExpr (Entity Favorite))
forall a a'. ToFrom a a' => a -> SqlQuery a'
from (forall ent. PersistEntity ent => From (SqlExpr (Entity ent))
table @Favorite)
      SqlQuery (SqlExpr (Entity Favorite))
-> (SqlExpr (Entity Favorite) -> SqlExpr (Value Bool))
-> SqlQuery (SqlExpr (Entity Favorite))
forall a. SqlQuery a -> (a -> SqlExpr (Value Bool)) -> SqlQuery a
`suchThat` \SqlExpr (Entity Favorite)
f' ->
        SqlExpr (Entity Article)
a.id SqlExpr (Value (Key Article))
-> SqlExpr (Value (Key Article)) -> SqlExpr (Value Bool)
forall typ.
PersistField typ =>
SqlExpr (Value typ) -> SqlExpr (Value typ) -> SqlExpr (Value Bool)
==. SqlExpr (Entity Favorite)
f'.article