{-# OPTIONS -fno-warn-orphans #-}
{-# LANGUAGE DeriveAnyClass #-}

module Hasura.Backends.MySQL.Types.Internal
  ( Aliased (..),
    ConnSourceConfig (..),
    SourceConfig (..),
    Column (..),
    JoinType (..),
    ScalarValue (..),
    Expression (..),
    Top (..),
    Op (..),
    ConnPoolSettings (..),
    FieldName (..),
    FieldOrigin (..),
    EntityAlias (..),
    Countable (..),
    Aggregate (..),
    Projection (..),
    TableName (..),
    From (..),
    Reselect (..),
    JoinAlias (..),
    Join (..),
    Where (..),
    Order (..),
    NullsOrder (..),
    ScalarType,
    OrderBy (..),
    Select (..),
    defaultConnPoolSettings,
    ConstraintName (..),
    FunctionName (..),
    parseMySQLScalarType,
    parseScalarValue,
    mkMySQLScalarTypeName,
  )
where

import Data.Aeson qualified as J
import Data.ByteString
import Data.Data
import Data.HashSet.InsOrd (InsOrdHashSet)
import Data.Hashable
import Data.Int
import Data.Pool
import Data.Set
import Data.Text qualified as T
import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
import Data.Text.Encoding.Error (lenientDecode)
import Data.Text.Extended (ToTxt (..))
import Data.Word (Word16)
import Database.MySQL.Base (Connection)
import Database.MySQL.Base.Types qualified as MySQLTypes (Type (..))
import Hasura.Base.Error
import Hasura.Base.ErrorValue qualified as ErrorValue
import Hasura.Base.ToErrorValue
import Hasura.Incremental.Internal.Dependency (Cacheable (..))
import Hasura.Prelude
import Language.GraphQL.Draft.Syntax qualified as G

data Aliased a = Aliased
  { Aliased a -> a
aliasedThing :: a,
    Aliased a -> Text
aliasedAlias :: Text
  }

-- | Partial of Database.MySQL.Simple.ConnectInfo
data ConnSourceConfig = ConnSourceConfig
  { -- | Works with @127.0.0.1@ but not with @localhost@: https://mariadb.com/kb/en/troubleshooting-connection-issues/#localhost-and
    ConnSourceConfig -> Text
_cscHost :: Text,
    ConnSourceConfig -> Word16
_cscPort :: Word16,
    ConnSourceConfig -> Text
_cscUser :: Text,
    ConnSourceConfig -> Text
_cscPassword :: Text,
    ConnSourceConfig -> Text
_cscDatabase :: Text,
    ConnSourceConfig -> ConnPoolSettings
_cscPoolSettings :: ConnPoolSettings
  }
  deriving (ConnSourceConfig -> ConnSourceConfig -> Bool
(ConnSourceConfig -> ConnSourceConfig -> Bool)
-> (ConnSourceConfig -> ConnSourceConfig -> Bool)
-> Eq ConnSourceConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConnSourceConfig -> ConnSourceConfig -> Bool
$c/= :: ConnSourceConfig -> ConnSourceConfig -> Bool
== :: ConnSourceConfig -> ConnSourceConfig -> Bool
$c== :: ConnSourceConfig -> ConnSourceConfig -> Bool
Eq, Int -> ConnSourceConfig -> ShowS
[ConnSourceConfig] -> ShowS
ConnSourceConfig -> String
(Int -> ConnSourceConfig -> ShowS)
-> (ConnSourceConfig -> String)
-> ([ConnSourceConfig] -> ShowS)
-> Show ConnSourceConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConnSourceConfig] -> ShowS
$cshowList :: [ConnSourceConfig] -> ShowS
show :: ConnSourceConfig -> String
$cshow :: ConnSourceConfig -> String
showsPrec :: Int -> ConnSourceConfig -> ShowS
$cshowsPrec :: Int -> ConnSourceConfig -> ShowS
Show, ConnSourceConfig -> ()
(ConnSourceConfig -> ()) -> NFData ConnSourceConfig
forall a. (a -> ()) -> NFData a
rnf :: ConnSourceConfig -> ()
$crnf :: ConnSourceConfig -> ()
NFData, (forall x. ConnSourceConfig -> Rep ConnSourceConfig x)
-> (forall x. Rep ConnSourceConfig x -> ConnSourceConfig)
-> Generic ConnSourceConfig
forall x. Rep ConnSourceConfig x -> ConnSourceConfig
forall x. ConnSourceConfig -> Rep ConnSourceConfig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ConnSourceConfig x -> ConnSourceConfig
$cfrom :: forall x. ConnSourceConfig -> Rep ConnSourceConfig x
Generic, Int -> ConnSourceConfig -> Int
ConnSourceConfig -> Int
(Int -> ConnSourceConfig -> Int)
-> (ConnSourceConfig -> Int) -> Hashable ConnSourceConfig
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: ConnSourceConfig -> Int
$chash :: ConnSourceConfig -> Int
hashWithSalt :: Int -> ConnSourceConfig -> Int
$chashWithSalt :: Int -> ConnSourceConfig -> Int
Hashable)

data SourceConfig = SourceConfig
  { SourceConfig -> ConnSourceConfig
scConfig :: ConnSourceConfig,
    SourceConfig -> Pool Connection
scConnectionPool :: Pool Connection
  }

newtype ConstraintName = ConstraintName {ConstraintName -> Text
unConstraintName :: Text}
  deriving newtype (Int -> ConstraintName -> ShowS
[ConstraintName] -> ShowS
ConstraintName -> String
(Int -> ConstraintName -> ShowS)
-> (ConstraintName -> String)
-> ([ConstraintName] -> ShowS)
-> Show ConstraintName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConstraintName] -> ShowS
$cshowList :: [ConstraintName] -> ShowS
show :: ConstraintName -> String
$cshow :: ConstraintName -> String
showsPrec :: Int -> ConstraintName -> ShowS
$cshowsPrec :: Int -> ConstraintName -> ShowS
Show, ConstraintName -> ConstraintName -> Bool
(ConstraintName -> ConstraintName -> Bool)
-> (ConstraintName -> ConstraintName -> Bool) -> Eq ConstraintName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConstraintName -> ConstraintName -> Bool
$c/= :: ConstraintName -> ConstraintName -> Bool
== :: ConstraintName -> ConstraintName -> Bool
$c== :: ConstraintName -> ConstraintName -> Bool
Eq, ConstraintName -> Text
(ConstraintName -> Text) -> ToTxt ConstraintName
forall a. (a -> Text) -> ToTxt a
toTxt :: ConstraintName -> Text
$ctoTxt :: ConstraintName -> Text
ToTxt, Value -> Parser [ConstraintName]
Value -> Parser ConstraintName
(Value -> Parser ConstraintName)
-> (Value -> Parser [ConstraintName]) -> FromJSON ConstraintName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ConstraintName]
$cparseJSONList :: Value -> Parser [ConstraintName]
parseJSON :: Value -> Parser ConstraintName
$cparseJSON :: Value -> Parser ConstraintName
J.FromJSON, [ConstraintName] -> Value
[ConstraintName] -> Encoding
ConstraintName -> Value
ConstraintName -> Encoding
(ConstraintName -> Value)
-> (ConstraintName -> Encoding)
-> ([ConstraintName] -> Value)
-> ([ConstraintName] -> Encoding)
-> ToJSON ConstraintName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [ConstraintName] -> Encoding
$ctoEncodingList :: [ConstraintName] -> Encoding
toJSONList :: [ConstraintName] -> Value
$ctoJSONList :: [ConstraintName] -> Value
toEncoding :: ConstraintName -> Encoding
$ctoEncoding :: ConstraintName -> Encoding
toJSON :: ConstraintName -> Value
$ctoJSON :: ConstraintName -> Value
J.ToJSON, Int -> ConstraintName -> Int
ConstraintName -> Int
(Int -> ConstraintName -> Int)
-> (ConstraintName -> Int) -> Hashable ConstraintName
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: ConstraintName -> Int
$chash :: ConstraintName -> Int
hashWithSalt :: Int -> ConstraintName -> Int
$chashWithSalt :: Int -> ConstraintName -> Int
Hashable, ConstraintName -> ()
(ConstraintName -> ()) -> NFData ConstraintName
forall a. (a -> ()) -> NFData a
rnf :: ConstraintName -> ()
$crnf :: ConstraintName -> ()
NFData, Eq ConstraintName
Eq ConstraintName
-> (Accesses -> ConstraintName -> ConstraintName -> Bool)
-> Cacheable ConstraintName
Accesses -> ConstraintName -> ConstraintName -> Bool
forall a. Eq a -> (Accesses -> a -> a -> Bool) -> Cacheable a
unchanged :: Accesses -> ConstraintName -> ConstraintName -> Bool
$cunchanged :: Accesses -> ConstraintName -> ConstraintName -> Bool
$cp1Cacheable :: Eq ConstraintName
Cacheable)

instance ToErrorValue ConstraintName where
  toErrorValue :: ConstraintName -> ErrorMessage
toErrorValue = Text -> ErrorMessage
ErrorValue.squote (Text -> ErrorMessage)
-> (ConstraintName -> Text) -> ConstraintName -> ErrorMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstraintName -> Text
unConstraintName

newtype FunctionName = FunctionName {FunctionName -> Text
unFunctionName :: Text}
  deriving newtype (Int -> FunctionName -> ShowS
[FunctionName] -> ShowS
FunctionName -> String
(Int -> FunctionName -> ShowS)
-> (FunctionName -> String)
-> ([FunctionName] -> ShowS)
-> Show FunctionName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FunctionName] -> ShowS
$cshowList :: [FunctionName] -> ShowS
show :: FunctionName -> String
$cshow :: FunctionName -> String
showsPrec :: Int -> FunctionName -> ShowS
$cshowsPrec :: Int -> FunctionName -> ShowS
Show, FunctionName -> FunctionName -> Bool
(FunctionName -> FunctionName -> Bool)
-> (FunctionName -> FunctionName -> Bool) -> Eq FunctionName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FunctionName -> FunctionName -> Bool
$c/= :: FunctionName -> FunctionName -> Bool
== :: FunctionName -> FunctionName -> Bool
$c== :: FunctionName -> FunctionName -> Bool
Eq, Eq FunctionName
Eq FunctionName
-> (FunctionName -> FunctionName -> Ordering)
-> (FunctionName -> FunctionName -> Bool)
-> (FunctionName -> FunctionName -> Bool)
-> (FunctionName -> FunctionName -> Bool)
-> (FunctionName -> FunctionName -> Bool)
-> (FunctionName -> FunctionName -> FunctionName)
-> (FunctionName -> FunctionName -> FunctionName)
-> Ord FunctionName
FunctionName -> FunctionName -> Bool
FunctionName -> FunctionName -> Ordering
FunctionName -> FunctionName -> FunctionName
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 :: FunctionName -> FunctionName -> FunctionName
$cmin :: FunctionName -> FunctionName -> FunctionName
max :: FunctionName -> FunctionName -> FunctionName
$cmax :: FunctionName -> FunctionName -> FunctionName
>= :: FunctionName -> FunctionName -> Bool
$c>= :: FunctionName -> FunctionName -> Bool
> :: FunctionName -> FunctionName -> Bool
$c> :: FunctionName -> FunctionName -> Bool
<= :: FunctionName -> FunctionName -> Bool
$c<= :: FunctionName -> FunctionName -> Bool
< :: FunctionName -> FunctionName -> Bool
$c< :: FunctionName -> FunctionName -> Bool
compare :: FunctionName -> FunctionName -> Ordering
$ccompare :: FunctionName -> FunctionName -> Ordering
$cp1Ord :: Eq FunctionName
Ord, FunctionName -> Text
(FunctionName -> Text) -> ToTxt FunctionName
forall a. (a -> Text) -> ToTxt a
toTxt :: FunctionName -> Text
$ctoTxt :: FunctionName -> Text
ToTxt, FromJSONKeyFunction [FunctionName]
FromJSONKeyFunction FunctionName
FromJSONKeyFunction FunctionName
-> FromJSONKeyFunction [FunctionName] -> FromJSONKey FunctionName
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [FunctionName]
$cfromJSONKeyList :: FromJSONKeyFunction [FunctionName]
fromJSONKey :: FromJSONKeyFunction FunctionName
$cfromJSONKey :: FromJSONKeyFunction FunctionName
J.FromJSONKey, ToJSONKeyFunction [FunctionName]
ToJSONKeyFunction FunctionName
ToJSONKeyFunction FunctionName
-> ToJSONKeyFunction [FunctionName] -> ToJSONKey FunctionName
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [FunctionName]
$ctoJSONKeyList :: ToJSONKeyFunction [FunctionName]
toJSONKey :: ToJSONKeyFunction FunctionName
$ctoJSONKey :: ToJSONKeyFunction FunctionName
J.ToJSONKey, Value -> Parser [FunctionName]
Value -> Parser FunctionName
(Value -> Parser FunctionName)
-> (Value -> Parser [FunctionName]) -> FromJSON FunctionName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [FunctionName]
$cparseJSONList :: Value -> Parser [FunctionName]
parseJSON :: Value -> Parser FunctionName
$cparseJSON :: Value -> Parser FunctionName
J.FromJSON, [FunctionName] -> Value
[FunctionName] -> Encoding
FunctionName -> Value
FunctionName -> Encoding
(FunctionName -> Value)
-> (FunctionName -> Encoding)
-> ([FunctionName] -> Value)
-> ([FunctionName] -> Encoding)
-> ToJSON FunctionName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [FunctionName] -> Encoding
$ctoEncodingList :: [FunctionName] -> Encoding
toJSONList :: [FunctionName] -> Value
$ctoJSONList :: [FunctionName] -> Value
toEncoding :: FunctionName -> Encoding
$ctoEncoding :: FunctionName -> Encoding
toJSON :: FunctionName -> Value
$ctoJSON :: FunctionName -> Value
J.ToJSON, Int -> FunctionName -> Int
FunctionName -> Int
(Int -> FunctionName -> Int)
-> (FunctionName -> Int) -> Hashable FunctionName
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: FunctionName -> Int
$chash :: FunctionName -> Int
hashWithSalt :: Int -> FunctionName -> Int
$chashWithSalt :: Int -> FunctionName -> Int
Hashable, Eq FunctionName
Eq FunctionName
-> (Accesses -> FunctionName -> FunctionName -> Bool)
-> Cacheable FunctionName
Accesses -> FunctionName -> FunctionName -> Bool
forall a. Eq a -> (Accesses -> a -> a -> Bool) -> Cacheable a
unchanged :: Accesses -> FunctionName -> FunctionName -> Bool
$cunchanged :: Accesses -> FunctionName -> FunctionName -> Bool
$cp1Cacheable :: Eq FunctionName
Cacheable, FunctionName -> ()
(FunctionName -> ()) -> NFData FunctionName
forall a. (a -> ()) -> NFData a
rnf :: FunctionName -> ()
$crnf :: FunctionName -> ()
NFData)

instance ToErrorValue FunctionName where
  toErrorValue :: FunctionName -> ErrorMessage
toErrorValue = Text -> ErrorMessage
ErrorValue.squote (Text -> ErrorMessage)
-> (FunctionName -> Text) -> FunctionName -> ErrorMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FunctionName -> Text
unFunctionName

newtype Column = Column {Column -> Text
unColumn :: Text}
  deriving newtype (Int -> Column -> ShowS
[Column] -> ShowS
Column -> String
(Int -> Column -> ShowS)
-> (Column -> String) -> ([Column] -> ShowS) -> Show Column
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Column] -> ShowS
$cshowList :: [Column] -> ShowS
show :: Column -> String
$cshow :: Column -> String
showsPrec :: Int -> Column -> ShowS
$cshowsPrec :: Int -> Column -> ShowS
Show, Column -> Column -> Bool
(Column -> Column -> Bool)
-> (Column -> Column -> Bool) -> Eq Column
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Column -> Column -> Bool
$c/= :: Column -> Column -> Bool
== :: Column -> Column -> Bool
$c== :: Column -> Column -> Bool
Eq, Eq Column
Eq Column
-> (Column -> Column -> Ordering)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Bool)
-> (Column -> Column -> Column)
-> (Column -> Column -> Column)
-> Ord Column
Column -> Column -> Bool
Column -> Column -> Ordering
Column -> Column -> Column
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 :: Column -> Column -> Column
$cmin :: Column -> Column -> Column
max :: Column -> Column -> Column
$cmax :: Column -> Column -> Column
>= :: Column -> Column -> Bool
$c>= :: Column -> Column -> Bool
> :: Column -> Column -> Bool
$c> :: Column -> Column -> Bool
<= :: Column -> Column -> Bool
$c<= :: Column -> Column -> Bool
< :: Column -> Column -> Bool
$c< :: Column -> Column -> Bool
compare :: Column -> Column -> Ordering
$ccompare :: Column -> Column -> Ordering
$cp1Ord :: Eq Column
Ord, Column -> Text
(Column -> Text) -> ToTxt Column
forall a. (a -> Text) -> ToTxt a
toTxt :: Column -> Text
$ctoTxt :: Column -> Text
ToTxt, FromJSONKeyFunction [Column]
FromJSONKeyFunction Column
FromJSONKeyFunction Column
-> FromJSONKeyFunction [Column] -> FromJSONKey Column
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [Column]
$cfromJSONKeyList :: FromJSONKeyFunction [Column]
fromJSONKey :: FromJSONKeyFunction Column
$cfromJSONKey :: FromJSONKeyFunction Column
J.FromJSONKey, ToJSONKeyFunction [Column]
ToJSONKeyFunction Column
ToJSONKeyFunction Column
-> ToJSONKeyFunction [Column] -> ToJSONKey Column
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [Column]
$ctoJSONKeyList :: ToJSONKeyFunction [Column]
toJSONKey :: ToJSONKeyFunction Column
$ctoJSONKey :: ToJSONKeyFunction Column
J.ToJSONKey, Value -> Parser [Column]
Value -> Parser Column
(Value -> Parser Column)
-> (Value -> Parser [Column]) -> FromJSON Column
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Column]
$cparseJSONList :: Value -> Parser [Column]
parseJSON :: Value -> Parser Column
$cparseJSON :: Value -> Parser Column
J.FromJSON, [Column] -> Value
[Column] -> Encoding
Column -> Value
Column -> Encoding
(Column -> Value)
-> (Column -> Encoding)
-> ([Column] -> Value)
-> ([Column] -> Encoding)
-> ToJSON Column
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Column] -> Encoding
$ctoEncodingList :: [Column] -> Encoding
toJSONList :: [Column] -> Value
$ctoJSONList :: [Column] -> Value
toEncoding :: Column -> Encoding
$ctoEncoding :: Column -> Encoding
toJSON :: Column -> Value
$ctoJSON :: Column -> Value
J.ToJSON, Int -> Column -> Int
Column -> Int
(Int -> Column -> Int) -> (Column -> Int) -> Hashable Column
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Column -> Int
$chash :: Column -> Int
hashWithSalt :: Int -> Column -> Int
$chashWithSalt :: Int -> Column -> Int
Hashable, Eq Column
Eq Column
-> (Accesses -> Column -> Column -> Bool) -> Cacheable Column
Accesses -> Column -> Column -> Bool
forall a. Eq a -> (Accesses -> a -> a -> Bool) -> Cacheable a
unchanged :: Accesses -> Column -> Column -> Bool
$cunchanged :: Accesses -> Column -> Column -> Bool
$cp1Cacheable :: Eq Column
Cacheable, Column -> ()
(Column -> ()) -> NFData Column
forall a. (a -> ()) -> NFData a
rnf :: Column -> ()
$crnf :: Column -> ()
NFData)
  deriving ((forall x. Column -> Rep Column x)
-> (forall x. Rep Column x -> Column) -> Generic Column
forall x. Rep Column x -> Column
forall x. Column -> Rep Column x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Column x -> Column
$cfrom :: forall x. Column -> Rep Column x
Generic)

instance ToErrorValue Column where
  toErrorValue :: Column -> ErrorMessage
toErrorValue = Text -> ErrorMessage
ErrorValue.squote (Text -> ErrorMessage)
-> (Column -> Text) -> Column -> ErrorMessage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Column -> Text
unColumn

data ScalarValue
  = BigValue Int32 -- Not Int64 due to scalar-representation
  | BinaryValue ByteString
  | BitValue Bool
  | BlobValue ByteString
  | CharValue Text
  | DatetimeValue Text
  | DateValue Text
  | DecimalValue Double -- Not Decimal due to scalar-representation
  | DoubleValue Double
  | EnumValue Text
  | FloatValue Double -- Not Float due to scalar-representation
  | GeometrycollectionValue Text -- TODO
  | GeometryValue Text -- TODO
  | IntValue Int32
  | JsonValue J.Value
  | LinestringValue Text -- TODO
  | MediumValue Int32 -- (actually, 3-bytes)
  | MultilinestringValue Text -- TODO
  | MultipointValue Text -- TODO
  | MultipolygonValue Text -- TODO
  | NullValue
  | NumericValue Double -- Not Decimal due to scalar-representation -- TODO: Double check
  | PointValue Text -- TODO
  | PolygonValue Text -- TODO
  | SetValue (Set Text)
  | SmallValue Int32 -- Not Int16 due to scalar-representation
  | TextValue Text
  | TimestampValue Text
  | TimeValue Text
  | TinyValue Int32 -- Not Int8 due to scalar-representation
  | UnknownValue Text
  | VarbinaryValue ByteString
  | VarcharValue Text
  | YearValue Text
  deriving (Int -> ScalarValue -> ShowS
[ScalarValue] -> ShowS
ScalarValue -> String
(Int -> ScalarValue -> ShowS)
-> (ScalarValue -> String)
-> ([ScalarValue] -> ShowS)
-> Show ScalarValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScalarValue] -> ShowS
$cshowList :: [ScalarValue] -> ShowS
show :: ScalarValue -> String
$cshow :: ScalarValue -> String
showsPrec :: Int -> ScalarValue -> ShowS
$cshowsPrec :: Int -> ScalarValue -> ShowS
Show, ReadPrec [ScalarValue]
ReadPrec ScalarValue
Int -> ReadS ScalarValue
ReadS [ScalarValue]
(Int -> ReadS ScalarValue)
-> ReadS [ScalarValue]
-> ReadPrec ScalarValue
-> ReadPrec [ScalarValue]
-> Read ScalarValue
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ScalarValue]
$creadListPrec :: ReadPrec [ScalarValue]
readPrec :: ReadPrec ScalarValue
$creadPrec :: ReadPrec ScalarValue
readList :: ReadS [ScalarValue]
$creadList :: ReadS [ScalarValue]
readsPrec :: Int -> ReadS ScalarValue
$creadsPrec :: Int -> ReadS ScalarValue
Read, ScalarValue -> ScalarValue -> Bool
(ScalarValue -> ScalarValue -> Bool)
-> (ScalarValue -> ScalarValue -> Bool) -> Eq ScalarValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ScalarValue -> ScalarValue -> Bool
$c/= :: ScalarValue -> ScalarValue -> Bool
== :: ScalarValue -> ScalarValue -> Bool
$c== :: ScalarValue -> ScalarValue -> Bool
Eq, Eq ScalarValue
Eq ScalarValue
-> (ScalarValue -> ScalarValue -> Ordering)
-> (ScalarValue -> ScalarValue -> Bool)
-> (ScalarValue -> ScalarValue -> Bool)
-> (ScalarValue -> ScalarValue -> Bool)
-> (ScalarValue -> ScalarValue -> Bool)
-> (ScalarValue -> ScalarValue -> ScalarValue)
-> (ScalarValue -> ScalarValue -> ScalarValue)
-> Ord ScalarValue
ScalarValue -> ScalarValue -> Bool
ScalarValue -> ScalarValue -> Ordering
ScalarValue -> ScalarValue -> ScalarValue
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 :: ScalarValue -> ScalarValue -> ScalarValue
$cmin :: ScalarValue -> ScalarValue -> ScalarValue
max :: ScalarValue -> ScalarValue -> ScalarValue
$cmax :: ScalarValue -> ScalarValue -> ScalarValue
>= :: ScalarValue -> ScalarValue -> Bool
$c>= :: ScalarValue -> ScalarValue -> Bool
> :: ScalarValue -> ScalarValue -> Bool
$c> :: ScalarValue -> ScalarValue -> Bool
<= :: ScalarValue -> ScalarValue -> Bool
$c<= :: ScalarValue -> ScalarValue -> Bool
< :: ScalarValue -> ScalarValue -> Bool
$c< :: ScalarValue -> ScalarValue -> Bool
compare :: ScalarValue -> ScalarValue -> Ordering
$ccompare :: ScalarValue -> ScalarValue -> Ordering
$cp1Ord :: Eq ScalarValue
Ord, (forall x. ScalarValue -> Rep ScalarValue x)
-> (forall x. Rep ScalarValue x -> ScalarValue)
-> Generic ScalarValue
forall x. Rep ScalarValue x -> ScalarValue
forall x. ScalarValue -> Rep ScalarValue x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ScalarValue x -> ScalarValue
$cfrom :: forall x. ScalarValue -> Rep ScalarValue x
Generic, [ScalarValue] -> Value
[ScalarValue] -> Encoding
ScalarValue -> Value
ScalarValue -> Encoding
(ScalarValue -> Value)
-> (ScalarValue -> Encoding)
-> ([ScalarValue] -> Value)
-> ([ScalarValue] -> Encoding)
-> ToJSON ScalarValue
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [ScalarValue] -> Encoding
$ctoEncodingList :: [ScalarValue] -> Encoding
toJSONList :: [ScalarValue] -> Value
$ctoJSONList :: [ScalarValue] -> Value
toEncoding :: ScalarValue -> Encoding
$ctoEncoding :: ScalarValue -> Encoding
toJSON :: ScalarValue -> Value
$ctoJSON :: ScalarValue -> Value
J.ToJSON, ToJSONKeyFunction [ScalarValue]
ToJSONKeyFunction ScalarValue
ToJSONKeyFunction ScalarValue
-> ToJSONKeyFunction [ScalarValue] -> ToJSONKey ScalarValue
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [ScalarValue]
$ctoJSONKeyList :: ToJSONKeyFunction [ScalarValue]
toJSONKey :: ToJSONKeyFunction ScalarValue
$ctoJSONKey :: ToJSONKeyFunction ScalarValue
J.ToJSONKey, Value -> Parser [ScalarValue]
Value -> Parser ScalarValue
(Value -> Parser ScalarValue)
-> (Value -> Parser [ScalarValue]) -> FromJSON ScalarValue
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ScalarValue]
$cparseJSONList :: Value -> Parser [ScalarValue]
parseJSON :: Value -> Parser ScalarValue
$cparseJSON :: Value -> Parser ScalarValue
J.FromJSON, Typeable ScalarValue
DataType
Constr
Typeable ScalarValue
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ScalarValue -> c ScalarValue)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ScalarValue)
-> (ScalarValue -> Constr)
-> (ScalarValue -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ScalarValue))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ScalarValue))
-> ((forall b. Data b => b -> b) -> ScalarValue -> ScalarValue)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ScalarValue -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ScalarValue -> r)
-> (forall u. (forall d. Data d => d -> u) -> ScalarValue -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ScalarValue -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue)
-> Data ScalarValue
ScalarValue -> DataType
ScalarValue -> Constr
(forall b. Data b => b -> b) -> ScalarValue -> ScalarValue
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScalarValue -> c ScalarValue
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScalarValue
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> ScalarValue -> u
forall u. (forall d. Data d => d -> u) -> ScalarValue -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScalarValue
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScalarValue -> c ScalarValue
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScalarValue)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScalarValue)
$cYearValue :: Constr
$cVarcharValue :: Constr
$cVarbinaryValue :: Constr
$cUnknownValue :: Constr
$cTinyValue :: Constr
$cTimeValue :: Constr
$cTimestampValue :: Constr
$cTextValue :: Constr
$cSmallValue :: Constr
$cSetValue :: Constr
$cPolygonValue :: Constr
$cPointValue :: Constr
$cNumericValue :: Constr
$cNullValue :: Constr
$cMultipolygonValue :: Constr
$cMultipointValue :: Constr
$cMultilinestringValue :: Constr
$cMediumValue :: Constr
$cLinestringValue :: Constr
$cJsonValue :: Constr
$cIntValue :: Constr
$cGeometryValue :: Constr
$cGeometrycollectionValue :: Constr
$cFloatValue :: Constr
$cEnumValue :: Constr
$cDoubleValue :: Constr
$cDecimalValue :: Constr
$cDateValue :: Constr
$cDatetimeValue :: Constr
$cCharValue :: Constr
$cBlobValue :: Constr
$cBitValue :: Constr
$cBinaryValue :: Constr
$cBigValue :: Constr
$tScalarValue :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
gmapMp :: (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
gmapM :: (forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ScalarValue -> m ScalarValue
gmapQi :: Int -> (forall d. Data d => d -> u) -> ScalarValue -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ScalarValue -> u
gmapQ :: (forall d. Data d => d -> u) -> ScalarValue -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ScalarValue -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScalarValue -> r
gmapT :: (forall b. Data b => b -> b) -> ScalarValue -> ScalarValue
$cgmapT :: (forall b. Data b => b -> b) -> ScalarValue -> ScalarValue
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScalarValue)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScalarValue)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c ScalarValue)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScalarValue)
dataTypeOf :: ScalarValue -> DataType
$cdataTypeOf :: ScalarValue -> DataType
toConstr :: ScalarValue -> Constr
$ctoConstr :: ScalarValue -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScalarValue
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScalarValue
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScalarValue -> c ScalarValue
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScalarValue -> c ScalarValue
$cp1Data :: Typeable ScalarValue
Data, ScalarValue -> ()
(ScalarValue -> ()) -> NFData ScalarValue
forall a. (a -> ()) -> NFData a
rnf :: ScalarValue -> ()
$crnf :: ScalarValue -> ()
NFData, Eq ScalarValue
Eq ScalarValue
-> (Accesses -> ScalarValue -> ScalarValue -> Bool)
-> Cacheable ScalarValue
Accesses -> ScalarValue -> ScalarValue -> Bool
forall a. Eq a -> (Accesses -> a -> a -> Bool) -> Cacheable a
unchanged :: Accesses -> ScalarValue -> ScalarValue -> Bool
$cunchanged :: Accesses -> ScalarValue -> ScalarValue -> Bool
$cp1Cacheable :: Eq ScalarValue
Cacheable)

instance Hashable ScalarValue where
  hashWithSalt :: Int -> ScalarValue -> Int
hashWithSalt Int
i = Int -> Text -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i (Text -> Int) -> (ScalarValue -> Text) -> ScalarValue -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScalarValue -> Text
forall a. Show a => a -> Text
tshow

instance ToTxt ScalarValue where
  toTxt :: ScalarValue -> Text
toTxt = ScalarValue -> Text
forall a. Show a => a -> Text
tshow

instance J.ToJSON ByteString where
  toJSON :: ByteString -> Value
toJSON = Text -> Value
J.String (Text -> Value) -> (ByteString -> Text) -> ByteString -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode

instance J.FromJSON ByteString where
  parseJSON :: Value -> Parser ByteString
parseJSON = String -> (Text -> Parser ByteString) -> Value -> Parser ByteString
forall a. String -> (Text -> Parser a) -> Value -> Parser a
J.withText String
"ByteString" (ByteString -> Parser ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Parser ByteString)
-> (Text -> ByteString) -> Text -> Parser ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8)

data Expression
  = ValueExpression ScalarValue
  | AndExpression [Expression]
  | OrExpression [Expression]
  | NotExpression Expression
  | ExistsExpression Select
  | InExpression Expression [Expression]
  | OpExpression Op Expression Expression
  | ColumnExpression FieldName
  | -- expression.text(e1, e2, ..)
    MethodExpression Expression Text [Expression]

data Top
  = NoTop
  | Top Int

data Op
  = LT
  | LTE
  | GT
  | GTE
  | IN
  | LIKE
  | NLIKE
  | NIN
  | EQ'
  | NEQ'

data ConnPoolSettings = ConnPoolSettings
  { ConnPoolSettings -> Word
_cscIdleTimeout :: Word,
    ConnPoolSettings -> Word
_cscMaxConnections :: Word
  }
  deriving (ConnPoolSettings -> ConnPoolSettings -> Bool
(ConnPoolSettings -> ConnPoolSettings -> Bool)
-> (ConnPoolSettings -> ConnPoolSettings -> Bool)
-> Eq ConnPoolSettings
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConnPoolSettings -> ConnPoolSettings -> Bool
$c/= :: ConnPoolSettings -> ConnPoolSettings -> Bool
== :: ConnPoolSettings -> ConnPoolSettings -> Bool
$c== :: ConnPoolSettings -> ConnPoolSettings -> Bool
Eq, Int -> ConnPoolSettings -> ShowS
[ConnPoolSettings] -> ShowS
ConnPoolSettings -> String
(Int -> ConnPoolSettings -> ShowS)
-> (ConnPoolSettings -> String)
-> ([ConnPoolSettings] -> ShowS)
-> Show ConnPoolSettings
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConnPoolSettings] -> ShowS
$cshowList :: [ConnPoolSettings] -> ShowS
show :: ConnPoolSettings -> String
$cshow :: ConnPoolSettings -> String
showsPrec :: Int -> ConnPoolSettings -> ShowS
$cshowsPrec :: Int -> ConnPoolSettings -> ShowS
Show, ConnPoolSettings -> ()
(ConnPoolSettings -> ()) -> NFData ConnPoolSettings
forall a. (a -> ()) -> NFData a
rnf :: ConnPoolSettings -> ()
$crnf :: ConnPoolSettings -> ()
NFData, (forall x. ConnPoolSettings -> Rep ConnPoolSettings x)
-> (forall x. Rep ConnPoolSettings x -> ConnPoolSettings)
-> Generic ConnPoolSettings
forall x. Rep ConnPoolSettings x -> ConnPoolSettings
forall x. ConnPoolSettings -> Rep ConnPoolSettings x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ConnPoolSettings x -> ConnPoolSettings
$cfrom :: forall x. ConnPoolSettings -> Rep ConnPoolSettings x
Generic, Int -> ConnPoolSettings -> Int
ConnPoolSettings -> Int
(Int -> ConnPoolSettings -> Int)
-> (ConnPoolSettings -> Int) -> Hashable ConnPoolSettings
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: ConnPoolSettings -> Int
$chash :: ConnPoolSettings -> Int
hashWithSalt :: Int -> ConnPoolSettings -> Int
$chashWithSalt :: Int -> ConnPoolSettings -> Int
Hashable)

data FieldName = FieldName
  { FieldName -> Text
fName :: Text,
    FieldName -> Text
fNameEntity :: Text
  }

data FieldOrigin
  = NoOrigin
  | AggregateOrigin [Aliased Aggregate]

newtype EntityAlias = EntityAlias
  { EntityAlias -> Text
entityAliasText :: Text
  }

data Countable name
  = StarCountable
  | NonNullFieldCountable (NonEmpty name)
  | DistinctCountable (NonEmpty name)

data Aggregate
  = CountAggregate (Countable FieldName)
  | OpAggregate Text [Expression]
  | TextAggregate Text

data Projection
  = ExpressionProjection (Aliased Expression)
  | FieldNameProjection (Aliased FieldName)
  | AggregateProjections (Aliased (NonEmpty (Aliased Aggregate)))
  | AggregateProjection (Aliased Aggregate)
  | StarProjection
  | EntityProjection (Aliased [(FieldName, FieldOrigin)])
  | ArrayEntityProjection EntityAlias (Aliased [FieldName])

data TableName = TableName
  { TableName -> Text
name :: Text,
    TableName -> Maybe Text
schema :: Maybe Text
  }

instance ToErrorValue TableName where
  toErrorValue :: TableName -> ErrorMessage
toErrorValue TableName {Text
name :: Text
name :: TableName -> Text
name, Maybe Text
schema :: Maybe Text
schema :: TableName -> Maybe Text
schema} =
    Text -> ErrorMessage
ErrorValue.squote (Text -> ErrorMessage) -> Text -> ErrorMessage
forall a b. (a -> b) -> a -> b
$ Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
name (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
name) Maybe Text
schema

data From
  = FromQualifiedTable (Aliased TableName)
  | FromSelect (Aliased Select)

data Reselect = Reselect
  { Reselect -> [Projection]
reselectProjections :: [Projection],
    Reselect -> Where
reselectWhere :: Where
  }

data JoinAlias = JoinAlias
  { JoinAlias -> Text
joinAliasEntity :: Text,
    JoinAlias -> Maybe Text
joinAliasField :: Maybe Text
  }

data Join = Join
  { -- | For display/debug purposes.
    Join -> EntityAlias
joinRightTable :: EntityAlias,
    -- | Where to pull the data from.
    Join -> Select
joinSelect :: Select,
    -- | Type of join to perform in-Haskell.
    Join -> JoinType
joinType :: JoinType,
    -- | Wrap the output in this field name.
    Join -> Text
joinFieldName :: Text,
    Join -> Top
joinTop :: Top,
    Join -> Maybe Int
joinOffset :: Maybe Int
  }

data JoinType
  = -- | A join without any 'ON x=y' construct. We're querying from a
    -- table and doing our own WHERE clauses.
    OnlessJoin
  | -- | An array join on the given fields.
    ArrayJoin [(FieldName, FieldName)]
  | -- | An array aggregate join.
    ArrayAggregateJoin [(FieldName, FieldName)]
  | -- | Simple object join on the fields.
    ObjectJoin [(FieldName, FieldName)]

newtype Where
  = Where [Expression]

data Order
  = Asc
  | Desc

data NullsOrder
  = NullsFirst
  | NullsLast
  | NullsAnyOrder

type ScalarType = MySQLTypes.Type

data OrderBy = OrderBy
  { OrderBy -> FieldName
orderByFieldName :: FieldName,
    OrderBy -> Order
orderByOrder :: Order,
    OrderBy -> NullsOrder
orderByNullsOrder :: NullsOrder,
    OrderBy -> Maybe ScalarType
orderByType :: Maybe ScalarType
  }

data Select = Select
  { Select -> InsOrdHashSet Projection
selectProjections :: InsOrdHashSet Projection,
    Select -> From
selectFrom :: From,
    Select -> [Join]
selectJoins :: [Join],
    Select -> Where
selectWhere :: Where,
    Select -> Maybe (NonEmpty OrderBy)
selectOrderBy :: Maybe (NonEmpty OrderBy),
    Select -> Maybe Int
selectSqlOffset :: Maybe Int,
    Select -> Top
selectSqlTop :: Top,
    Select -> [FieldName]
selectGroupBy :: [FieldName],
    Select -> Maybe [Text]
selectFinalWantedFields :: Maybe [Text]
  }

mkMySQLScalarTypeName :: MonadError QErr m => ScalarType -> m G.Name
mkMySQLScalarTypeName :: ScalarType -> m Name
mkMySQLScalarTypeName = \case
  ScalarType
scalarType ->
    Text -> Maybe Name
G.mkName (ScalarType -> Text
scalarTypeDBName ScalarType
scalarType)
      Maybe Name -> m Name -> m Name
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` Code -> Text -> m Name
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400
        Code
ValidationFailed
        ( Text
"cannot use SQL type " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ScalarType -> Text
scalarTypeDBName ScalarType
scalarType Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" in the GraphQL schema because its name is not a "
            Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"valid GraphQL identifier"
        )

scalarTypeDBName :: ScalarType -> Text
scalarTypeDBName :: ScalarType -> Text
scalarTypeDBName = String -> ScalarType -> Text
forall a. HasCallStack => String -> a
error String
"scalarTypeDBName: not implemented"

defaultConnPoolSettings :: ConnPoolSettings
defaultConnPoolSettings :: ConnPoolSettings
defaultConnPoolSettings =
  ConnPoolSettings :: Word -> Word -> ConnPoolSettings
ConnPoolSettings
    { _cscIdleTimeout :: Word
_cscIdleTimeout = Word
5,
      _cscMaxConnections :: Word
_cscMaxConnections = Word
50
    }

-- | ref: https://dev.mysql.com/doc/c-api/8.0/en/c-api-data-structures.html
--
-- DB has CHAR, BINARY, VARCHAR and VARBINARY
-- C API only has STRING and VARSTRING
-- Database.MySQL.Base.Types.Type has String, VarString and VarChar for some reason
parseMySQLScalarType :: Text -> ScalarType
parseMySQLScalarType :: Text -> ScalarType
parseMySQLScalarType Text
scalarType =
  case (Text -> Text
T.toUpper Text
scalarType) of
    Text
"BIGINT" -> ScalarType
MySQLTypes.LongLong
    Text
"BINARY" -> ScalarType
MySQLTypes.String
    Text
"BIT" -> ScalarType
MySQLTypes.Bit
    Text
"BLOB" -> ScalarType
MySQLTypes.Blob -- TinyBlob, MediumBlob, LongBlob
    Text
"CHAR" -> ScalarType
MySQLTypes.String
    Text
"DATE" -> ScalarType
MySQLTypes.Date -- Or NewDate. REVIEW: When to use NewDate :: Database.MySQL.Base.Types.Type then?
    Text
"DATETIME" -> ScalarType
MySQLTypes.DateTime
    Text
"DECIMAL" -> ScalarType
MySQLTypes.Decimal -- Or NewDecimal
    Text
"DOUBLE" -> ScalarType
MySQLTypes.Double
    Text
"ENUM" -> ScalarType
MySQLTypes.Enum
    Text
"FLOAT" -> ScalarType
MySQLTypes.Float
    Text
"GEOMETRYCOLLECTION" -> ScalarType
MySQLTypes.Geometry
    Text
"GEOMETRY" -> ScalarType
MySQLTypes.Geometry -- For all Geometry types. TODO: Check how to distinguish between these types when it becomes necessary
    Text
"INT" -> ScalarType
MySQLTypes.Long
    Text
"JSON" -> ScalarType
MySQLTypes.Json
    Text
"LINESTRING" -> ScalarType
MySQLTypes.Geometry -- For now Geometry could be considered as Text
    Text
"MEDIUMINT" -> ScalarType
MySQLTypes.Int24
    Text
"MULTILINESTRING" -> ScalarType
MySQLTypes.Geometry
    Text
"MULTIPOINT" -> ScalarType
MySQLTypes.Geometry
    Text
"MULTIPOLYGON" -> ScalarType
MySQLTypes.Geometry
    Text
"NULL" -> ScalarType
MySQLTypes.Null -- Not a column type, but we retain it as part of this definition to enumerate all possible types
    Text
"NUMERIC" -> ScalarType
MySQLTypes.Decimal -- Or NewDecimal
    Text
"POINT" -> ScalarType
MySQLTypes.Geometry
    Text
"POLYGON" -> ScalarType
MySQLTypes.Geometry
    Text
"SET" -> ScalarType
MySQLTypes.Set
    Text
"SMALLINT" -> ScalarType
MySQLTypes.Short
    Text
"TEXT" -> ScalarType
MySQLTypes.Blob
    Text
"TIME" -> ScalarType
MySQLTypes.Time
    Text
"TIMESTAMP" -> ScalarType
MySQLTypes.Timestamp
    Text
"TINYINT" -> ScalarType
MySQLTypes.Tiny
    Text
"VARBINARY" -> ScalarType
MySQLTypes.VarString
    Text
"VARCHAR" -> ScalarType
MySQLTypes.VarChar
    Text
"YEAR" -> ScalarType
MySQLTypes.Year
    Text
"TINYTEXT" -> ScalarType
MySQLTypes.String
    Text
"VARCHAR(45)" -> ScalarType
MySQLTypes.VarChar
    Text
"VARCHAR(450)" -> ScalarType
MySQLTypes.VarChar
    Text
"INT UNSIGNED" -> ScalarType
MySQLTypes.Long
    Text
"BIT(1)" -> ScalarType
MySQLTypes.Bit
    -- _ -> MySQLTypes.Null

    Text
txt | Text
"INT" Text -> Text -> Bool
`T.isPrefixOf` Text
txt -> ScalarType
MySQLTypes.Long
    Text
txt -> String -> ScalarType
forall a. HasCallStack => String -> a
error (String -> ScalarType) -> String -> ScalarType
forall a b. (a -> b) -> a -> b
$ String
"parseMySQLScalartype: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
txt

parseScalarValue :: ScalarType -> J.Value -> Either QErr (ScalarValue)
parseScalarValue :: ScalarType -> Value -> Either QErr ScalarValue
parseScalarValue = String -> ScalarType -> Value -> Either QErr ScalarValue
forall a. HasCallStack => String -> a
error String
"parseScalarValue is yet to be implemented."