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 { Sql -> Text unSql :: Text } deriving stock (Sql -> Sql -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Sql -> Sql -> Bool $c/= :: Sql -> Sql -> Bool == :: Sql -> Sql -> Bool $c== :: Sql -> Sql -> Bool Eq, Int -> Sql -> ShowS [Sql] -> ShowS Sql -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Sql] -> ShowS $cshowList :: [Sql] -> ShowS show :: Sql -> String $cshow :: Sql -> String showsPrec :: Int -> Sql -> ShowS $cshowsPrec :: Int -> Sql -> ShowS Show, forall x. Rep Sql x -> Sql forall x. Sql -> Rep Sql x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep Sql x -> Sql $cfrom :: forall x. Sql -> Rep Sql x Generic, Eq Sql Sql -> Sql -> Bool Sql -> Sql -> Ordering Sql -> Sql -> Sql forall a. Eq a -> (a -> a -> Ordering) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> Bool) -> (a -> a -> a) -> (a -> a -> a) -> Ord a min :: Sql -> Sql -> Sql $cmin :: Sql -> Sql -> Sql max :: Sql -> Sql -> Sql $cmax :: Sql -> Sql -> Sql >= :: Sql -> Sql -> Bool $c>= :: Sql -> Sql -> Bool > :: Sql -> Sql -> Bool $c> :: Sql -> Sql -> Bool <= :: Sql -> Sql -> Bool $c<= :: Sql -> Sql -> Bool < :: Sql -> Sql -> Bool $c< :: Sql -> Sql -> Bool compare :: Sql -> Sql -> Ordering $ccompare :: Sql -> Sql -> Ordering Ord) deriving newtype (String -> Sql forall a. (String -> a) -> IsString a fromString :: String -> Sql $cfromString :: String -> Sql IsString, NonEmpty Sql -> Sql Sql -> Sql -> Sql forall b. Integral b => b -> Sql -> Sql forall a. (a -> a -> a) -> (NonEmpty a -> a) -> (forall b. Integral b => b -> a -> a) -> Semigroup a stimes :: forall b. Integral b => b -> Sql -> Sql $cstimes :: forall b. Integral b => b -> Sql -> Sql sconcat :: NonEmpty Sql -> Sql $csconcat :: NonEmpty Sql -> Sql <> :: Sql -> Sql -> Sql $c<> :: Sql -> Sql -> Sql Semigroup, Semigroup Sql Sql [Sql] -> Sql Sql -> Sql -> Sql forall a. Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a mconcat :: [Sql] -> Sql $cmconcat :: [Sql] -> Sql mappend :: Sql -> Sql -> Sql $cmappend :: Sql -> Sql -> Sql mempty :: Sql $cmempty :: Sql Monoid, [Sql] -> Encoding [Sql] -> Value Sql -> Encoding Sql -> Value forall a. (a -> Value) -> (a -> Encoding) -> ([a] -> Value) -> ([a] -> Encoding) -> ToJSON a toEncodingList :: [Sql] -> Encoding $ctoEncodingList :: [Sql] -> Encoding toJSONList :: [Sql] -> Value $ctoJSONList :: [Sql] -> Value toEncoding :: Sql -> Encoding $ctoEncoding :: Sql -> Encoding toJSON :: Sql -> Value $ctoJSON :: Sql -> Value ToJSON, Value -> Parser [Sql] Value -> Parser Sql forall a. (Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a parseJSONList :: Value -> Parser [Sql] $cparseJSONList :: Value -> Parser [Sql] parseJSON :: Value -> Parser Sql $cparseJSON :: Value -> Parser Sql FromJSON) instance ConvertUtf8 Text bs => ConvertUtf8 Sql bs where encodeUtf8 :: Sql -> bs encodeUtf8 = forall a b. ConvertUtf8 a b => a -> b encodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c . Sql -> Text unSql decodeUtf8 :: bs -> Sql decodeUtf8 = Text -> Sql Sql forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. ConvertUtf8 a b => b -> a decodeUtf8 decodeUtf8Strict :: bs -> Either UnicodeException Sql decodeUtf8Strict = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Text -> Sql Sql forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. ConvertUtf8 a b => b -> Either UnicodeException a decodeUtf8Strict instance Pretty Sql where pretty :: forall ann. Sql -> Doc ann pretty (Sql Text s) = forall a ann. Pretty a => a -> Doc ann pretty Text s sql :: QuasiQuoter sql :: QuasiQuoter sql = Maybe (Q Exp, Q Exp) -> Bool -> Bool -> QuasiQuoter exonWith (forall a. a -> Maybe a Just ([e|SkipWs|], [e|skipWs|])) Bool True Bool False class ToSql a where toSql :: a -> Sql instance ToSql Sql where toSql :: Sql -> Sql toSql = forall a. a -> a id instance {-# incoherent #-} ToSql a => ToSegment a Sql where toSegment :: a -> Sql toSegment = forall a. ToSql a => a -> Sql toSql instance ExonExpression (SkipWs Sql) Text builder where exonExpression :: (Text -> builder) -> Text -> Result builder exonExpression Text -> builder builder Text expr | Text -> Bool Text.null Text expr = forall a. Result a Empty | Bool otherwise = forall a. a -> Result a Result (Text -> builder builder Text expr) instance ExonAppend (SkipWs Sql) Text.Builder where exonConcat :: NonEmpty (Result Builder) -> Result Builder exonConcat (Result Builder h :| [Result Builder] t) = forall {a}. (IsString a, ExonAppend Sql a) => Result a -> [Result a] -> Result a go Result Builder h [Result Builder] t where go :: Result a -> [Result a] -> Result a go Result a Empty (Result a seg : [Result a] segs) = Result a -> [Result a] -> Result a go Result a seg [Result a] segs go Result a z (Result a Empty : Result a Empty : [Result a] segs) = Result a -> [Result a] -> Result a go Result a z (forall a. Result a Empty forall a. a -> [a] -> [a] : [Result a] segs) go Result a z [Item [Result a] Result a Empty] = Result a z go Result a z (Result a Empty : [Result a] segs) = Result a -> [Result a] -> Result a go Result a z (forall a. a -> Result a Result a " " forall a. a -> [a] -> [a] : [Result a] segs) go (Result a z) (Result a seg : [Result a] segs) = Result a -> [Result a] -> Result a go (forall result builder. ExonAppend result builder => builder -> builder -> Result builder exonAppend @Sql a z a seg) [Result a] segs go Result a z [] = Result a z sqlQuote :: Text -> Sql sqlQuote :: Text -> Sql sqlQuote = Text -> Sql Sql forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Exon a => a -> a dquote