module Sqel.Query.SelectExpr where
import Generics.SOP (All, K (K), NP ((:*)), hcmap, hcollapse)
import Sqel.Class.Mods (GetMod (getMod), MaybeMod (maybeMod))
import Sqel.Data.Dd (
Comp (Prod, Sum),
CompInc (Merge, Nest),
Dd (Dd),
DdInc (DdMerge, DdNest),
DdK (DdK),
DdSort (DdSum),
DdStruct (DdComp, DdPrim),
QOp (QAnd),
Struct (Comp, Prim),
)
import Sqel.Data.FragType (FragType (Where))
import Sqel.Data.Mods (Ignore (Ignore))
import Sqel.Data.Sel (Sel (SelSymbol, SelUnused), SelW (SelWAuto))
import Sqel.Data.SelectExpr (
SelectAtom (SelectAtom),
SelectExpr (SelectExprAtom, SelectExprIgnore, SelectExprList, SelectExprSum),
)
import Sqel.Data.Selector (Selector (Selector))
import Sqel.Data.Sql (Sql (Sql), sql)
import Sqel.Prim (IndexColumn)
import Sqel.Query.Combinators (whereEq)
import Sqel.Query.Fragments (ColumnPrefix, QFragmentPrefix (qfragmentPrefix), prefixed)
import Sqel.Sql.Prepared (dollar)
import Sqel.Text.DbIdentifier (dbSymbol)
guardSum :: SelectExpr -> SelectExpr
guardSum :: SelectExpr -> SelectExpr
guardSum = \case
SelectExprAtom FragType
Where Int -> Sql
code -> FragType -> (Int -> Sql) -> SelectExpr
SelectExprAtom FragType
Where \ Int
i -> [sql|(#{dollar i} is null or #{code i})|]
SelectExprList QOp
op [SelectExpr]
sub -> QOp -> [SelectExpr] -> SelectExpr
SelectExprList QOp
op (SelectExpr -> SelectExpr
guardSum forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SelectExpr]
sub)
SelectExpr
expr -> SelectExpr
expr
class ToSelectExpr query where
toSelectExpr :: ColumnPrefix -> Dd query -> SelectExpr
instance (
GetMod () SelectAtom ps,
MaybeMod Ignore ps
) => ToSelectExpr ('DdK 'SelUnused ps q 'Prim) where
toSelectExpr :: ColumnPrefix -> Dd ('DdK 'SelUnused ps q 'Prim) -> SelectExpr
toSelectExpr ColumnPrefix
_ (Dd SelW sel
_ Mods mods
p DdStruct s1
DdPrim) =
case forall p (ps :: [*]). MaybeMod p ps => Mods ps -> Maybe p
maybeMod Mods mods
p of
Just Ignore
Ignore -> SelectExpr
SelectExprIgnore
Maybe Ignore
Nothing -> FragType -> (Int -> Sql) -> SelectExpr
SelectExprAtom FragType
type_ (Selector -> Int -> Sql
code Selector
"")
where
SelectAtom FragType
type_ Selector -> Int -> Sql
code = forall (c :: Constraint) p (ps :: [*]).
GetMod c p ps =>
(c => p) -> Mods ps -> p
getMod @() SelectAtom
whereEq Mods mods
p
instance (
KnownSymbol n,
GetMod () SelectAtom ps
) => ToSelectExpr ('DdK ('SelSymbol n) ps q 'Prim) where
toSelectExpr :: ColumnPrefix -> Dd ('DdK ('SelSymbol n) ps q 'Prim) -> SelectExpr
toSelectExpr ColumnPrefix
pre (Dd SelW sel
_ Mods mods
p DdStruct s1
DdPrim) =
FragType -> (Int -> Sql) -> SelectExpr
SelectExprAtom FragType
type_ (Selector -> Int -> Sql
code (Sql -> Selector
Selector (Text -> Sql
Sql (Text -> ColumnPrefix -> Text
prefixed (forall (name :: Symbol). KnownSymbol name => Text
dbSymbol @n) ColumnPrefix
pre))))
where
SelectAtom FragType
type_ Selector -> Int -> Sql
code = forall (c :: Constraint) p (ps :: [*]).
GetMod c p ps =>
(c => p) -> Mods ps -> p
getMod @() SelectAtom
whereEq Mods mods
p
prodSelectExpr ::
∀ sel s .
All ToSelectExpr s =>
QFragmentPrefix sel =>
SelW sel ->
ColumnPrefix ->
QOp ->
NP Dd s ->
SelectExpr
prodSelectExpr :: forall (sel :: Sel) (s :: [DdK]).
(All ToSelectExpr s, QFragmentPrefix sel) =>
SelW sel -> ColumnPrefix -> QOp -> NP Dd s -> SelectExpr
prodSelectExpr SelW sel
sel ColumnPrefix
pre QOp
op =
QOp -> [SelectExpr] -> SelectExpr
SelectExprList QOp
op forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k l (h :: (k -> *) -> l -> *) (xs :: l) a.
(HCollapse h, SListIN h xs) =>
h (K a) xs -> CollapseTo h a
hcollapse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {l} (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
(xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *)
(f' :: k -> *).
(AllN (Prod h) c xs, HAp h) =>
proxy c
-> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs
hcmap (forall {k} (t :: k). Proxy t
Proxy @ToSelectExpr) (forall k a (b :: k). a -> K a b
K forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (query :: DdK).
ToSelectExpr query =>
ColumnPrefix -> Dd query -> SelectExpr
toSelectExpr (forall (sel :: Sel).
QFragmentPrefix sel =>
SelW sel -> ColumnPrefix -> ColumnPrefix
qfragmentPrefix SelW sel
sel ColumnPrefix
pre))
sumSelectExpr ::
∀ sel s .
All ToSelectExpr s =>
QFragmentPrefix sel =>
SelW sel ->
ColumnPrefix ->
NP Dd s ->
SelectExpr
sumSelectExpr :: forall (sel :: Sel) (s :: [DdK]).
(All ToSelectExpr s, QFragmentPrefix sel) =>
SelW sel -> ColumnPrefix -> NP Dd s -> SelectExpr
sumSelectExpr SelW sel
sel ColumnPrefix
pre =
[SelectExpr] -> SelectExpr
SelectExprSum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k l (h :: (k -> *) -> l -> *) (xs :: l) a.
(HCollapse h, SListIN h xs) =>
h (K a) xs -> CollapseTo h a
hcollapse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {l} (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
(xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *)
(f' :: k -> *).
(AllN (Prod h) c xs, HAp h) =>
proxy c
-> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs
hcmap (forall {k} (t :: k). Proxy t
Proxy @ToSelectExpr) (forall k a (b :: k). a -> K a b
K forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (query :: DdK).
ToSelectExpr query =>
ColumnPrefix -> Dd query -> SelectExpr
toSelectExpr (forall (sel :: Sel).
QFragmentPrefix sel =>
SelW sel -> ColumnPrefix -> ColumnPrefix
qfragmentPrefix SelW sel
sel ColumnPrefix
pre))
instance (
All ToSelectExpr sub,
QFragmentPrefix sel
) => ToSelectExpr ('DdK sel p q ('Comp tsel ('Prod con) 'Nest sub)) where
toSelectExpr :: ColumnPrefix
-> Dd ('DdK sel p q ('Comp tsel ('Prod con) 'Nest sub))
-> SelectExpr
toSelectExpr ColumnPrefix
pre = \case
Dd SelW sel
sel Mods mods
_ (DdComp TSelW sel
_ DdSort c
_ DdInc i
DdNest NP Dd sub
sub) ->
forall (sel :: Sel) (s :: [DdK]).
(All ToSelectExpr s, QFragmentPrefix sel) =>
SelW sel -> ColumnPrefix -> QOp -> NP Dd s -> SelectExpr
prodSelectExpr SelW sel
sel ColumnPrefix
pre QOp
QAnd NP Dd sub
sub
instance (
All ToSelectExpr sub
) => ToSelectExpr ('DdK sel p q ('Comp tsel ('Prod con) 'Merge sub)) where
toSelectExpr :: ColumnPrefix
-> Dd ('DdK sel p q ('Comp tsel ('Prod con) 'Merge sub))
-> SelectExpr
toSelectExpr ColumnPrefix
pre = \case
Dd SelW sel
_ Mods mods
_ (DdComp TSelW sel
_ DdSort c
_ DdInc i
DdMerge NP Dd sub
sub) ->
forall (sel :: Sel) (s :: [DdK]).
(All ToSelectExpr s, QFragmentPrefix sel) =>
SelW sel -> ColumnPrefix -> QOp -> NP Dd s -> SelectExpr
prodSelectExpr SelW 'SelAuto
SelWAuto ColumnPrefix
pre QOp
QAnd NP Dd sub
sub
instance (
All ToSelectExpr sub,
QFragmentPrefix sel
) => ToSelectExpr ('DdK sel p q ('Comp tsel 'Sum 'Nest (IndexColumn name : sub))) where
toSelectExpr :: ColumnPrefix
-> Dd
('DdK sel p q ('Comp tsel 'Sum 'Nest (IndexColumn name : sub)))
-> SelectExpr
toSelectExpr ColumnPrefix
pre = \case
Dd SelW sel
sel Mods mods
_ (DdComp TSelW sel
_ DdSort c
DdSum DdInc i
DdNest (Dd x
_ :* NP Dd xs
sub)) ->
SelectExpr -> SelectExpr
guardSum (forall (sel :: Sel) (s :: [DdK]).
(All ToSelectExpr s, QFragmentPrefix sel) =>
SelW sel -> ColumnPrefix -> NP Dd s -> SelectExpr
sumSelectExpr SelW sel
sel ColumnPrefix
pre NP Dd xs
sub)