sqel-0.0.1.0: lib/Sqel/Data/Sql.hs
module Sqel.Data.Sql where
import Data.Aeson (FromJSON, ToJSON)
import Data.Generics.Labels ()
import qualified Data.Text as Text
import qualified Data.Text.Lazy.Builder as Text
import Exon (
ExonAppend (exonAppend, exonConcat),
ExonExpression (exonExpression),
Result (Empty, Result),
SkipWs (SkipWs),
ToSegment (toSegment),
exonWith,
skipWs,
)
import Language.Haskell.TH.Quote (QuasiQuoter)
import Prettyprinter (Pretty (pretty))
import Sqel.Text.Quote (dquote)
newtype Sql = Sql { unSql :: Text }
deriving stock (Eq, Show, Generic, Ord)
deriving newtype (IsString, Semigroup, Monoid, ToJSON, FromJSON)
instance ConvertUtf8 Text bs => ConvertUtf8 Sql bs where
encodeUtf8 = encodeUtf8 . unSql
decodeUtf8 = Sql . decodeUtf8
decodeUtf8Strict = fmap Sql . decodeUtf8Strict
instance Pretty Sql where
pretty (Sql s) = pretty s
sql :: QuasiQuoter
sql = exonWith (Just ([e|SkipWs|], [e|skipWs|])) True False
class ToSql a where
toSql :: a -> Sql
instance ToSql Sql where
toSql = id
instance {-# incoherent #-} ToSql a => ToSegment a Sql where
toSegment = toSql
instance ExonExpression (SkipWs Sql) Text builder where
exonExpression builder expr
| Text.null expr = Empty
| otherwise = Result (builder expr)
instance ExonAppend (SkipWs Sql) Text.Builder where
exonConcat (h :| t) =
go h t
where
go Empty (seg : segs) = go seg segs
go z (Empty : Empty : segs) = go z (Empty : segs)
go z [Empty] = z
go z (Empty : segs) = go z (Result " " : segs)
go (Result z) (Result seg : segs) = go (exonAppend @Sql z seg) segs
go z [] = z
sqlQuote :: Text -> Sql
sqlQuote = Sql . dquote