packages feed

hasql-interpolate-1.1.0.0: lib/Hasql/Interpolate/Internal/Sql.hs

{-# LANGUAGE OverloadedStrings #-}

module Hasql.Interpolate.Internal.Sql
  ( Sql (..),
  )
where

import Control.Monad.Trans.State.Strict
import Data.String (IsString (..))
import qualified Data.Text.Lazy.Builder as Builder
import Hasql.Encoders

-- | A SQL string with interpolated expressions.
data Sql = Sql
  { -- | The sql string. It is stateful over an 'Int' in order to
    -- assign the postgresql parameter placeholders (e.g. @$1@, @$2@)
    sqlTxt :: State Int Builder.Builder,
    -- | The encoders associated with the sql string. Already applied
    -- to their parameters.
    encoder :: Params ()
  }

instance IsString Sql where
  fromString str = Sql (pure (Builder.fromString str)) mempty

instance Semigroup Sql where
  a <> b =
    Sql
      { sqlTxt =
          ((<>) <$> sqlTxt a <*> sqlTxt b),
        encoder = encoder a <> encoder b
      }
  {-# INLINE (<>) #-}

instance Monoid Sql where
  mempty =
    Sql
      { sqlTxt = pure mempty,
        encoder = mempty
      }
  {-# INLINE mempty #-}