packages feed

sqel-0.0.1.0: lib/Sqel/Query/Fragments.hs

module Sqel.Query.Fragments where

import Data.Composition ((.:))
import qualified Exon
import Exon (exon)

import Sqel.Data.Codec (ColumnName (ColumnName))
import Sqel.Data.Dd (QOp (QAnd, QOr))
import Sqel.Data.FragType (FragType (Where))
import Sqel.Data.Sel (Sel (SelAuto, SelSymbol, SelUnused), SelW (SelWSymbol))
import Sqel.Data.Sql (Sql, sql)
import Sqel.Names (ddName)
import Sqel.Sql.Prepared (dollar)
import Sqel.Text.DbIdentifier (quotedDbId)

parens :: Sql -> Sql
parens s =
  [sql|(#{s})|]

joinOp :: QOp -> [Sql] -> Sql
joinOp =
  parens .: Exon.intercalate . sep
  where
    sep = \case
      QAnd -> " and "
      QOr -> " or "

joinFrag :: QOp -> FragType -> [Sql] -> Sql
joinFrag op = \case
  Where ->
    joinOp op
  _ ->
    fold . head

guardCon :: Int -> Int -> Sql -> Sql
guardCon index con code =
  [exon|(#{dollar index} = #{show con} and #{code})|]

joinSum :: Int -> FragType -> [Sql] -> Sql
joinSum index Where =
  joinOp QOr . fmap (uncurry (guardCon index)) . zip [0..]
joinSum _  _ =
  fold . head

data ColumnPrefix =
  NoPrefix
  |
  BasePrefix Text
  |
  TypePrefix Text
  deriving stock (Eq, Show)

-- TODO this quotes the segments that seem to work fine, while the ones in PgTable don't.
addPrefix ::
  ColumnName ->
  ColumnPrefix ->
  ColumnPrefix
addPrefix (ColumnName segment) = \case
  NoPrefix -> BasePrefix (quotedDbId segment)
  BasePrefix name -> TypePrefix [exon|(#{name}).#{quotedDbId segment}|]
  TypePrefix prefix -> TypePrefix [exon|#{prefix}.#{quotedDbId segment}|]

prefixed :: Text -> ColumnPrefix -> Text
prefixed name = \case
  NoPrefix -> quotedDbId name
  BasePrefix prefix -> [exon|(#{prefix}).#{quotedDbId name}|]
  TypePrefix prefix -> [exon|#{prefix}.#{quotedDbId name}|]

class QFragmentPrefix sel where
  qfragmentPrefix :: SelW sel -> ColumnPrefix -> ColumnPrefix

instance QFragmentPrefix ('SelSymbol n) where
  qfragmentPrefix (SelWSymbol _) = addPrefix (ddName @n)

instance QFragmentPrefix 'SelAuto where
  qfragmentPrefix _ = id

instance QFragmentPrefix 'SelUnused where
  qfragmentPrefix _ = id