module ClickHaskell.Primitive.TLowCardinality where

-- Internal
import ClickHaskell.Primitive.Serialization
import ClickHaskell.Primitive.TString
import ClickHaskell.Primitive.TNullable

-- GHC included
import Control.DeepSeq (NFData)
import Data.String (IsString (..))
import GHC.TypeLits (ErrorMessage (..), TypeError)


-- * LowCardinality

-- | ClickHouse LowCardinality(T) column type
newtype LowCardinality chType = MkLowCardinality chType
instance IsLowCardinalitySupported chType => IsChType (LowCardinality chType)
  where
  chTypeName :: String
chTypeName = String
"LowCardinality(" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> forall chType. IsChType chType => String
chTypeName @chType String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
")"
  defaultValueOfTypeName :: LowCardinality chType
defaultValueOfTypeName = chType -> LowCardinality chType
forall chType. chType -> LowCardinality chType
MkLowCardinality (chType -> LowCardinality chType)
-> chType -> LowCardinality chType
forall a b. (a -> b) -> a -> b
$ forall chType. IsChType chType => chType
defaultValueOfTypeName @chType

deriving newtype instance (Eq chType, IsLowCardinalitySupported chType) => Eq (LowCardinality chType)
deriving newtype instance (NFData chType, IsLowCardinalitySupported chType) => NFData (LowCardinality chType)
deriving newtype instance IsString (LowCardinality ChString)

class IsChType chType => IsLowCardinalitySupported chType
instance IsLowCardinalitySupported ChString
instance
  ( IsLowCardinalitySupported chType
  , IsChType (Nullable chType)
  ) =>
  IsLowCardinalitySupported (Nullable chType)

instance {-# OVERLAPPABLE #-}
  ( IsChType chType
  , TypeError
    (    'Text "LowCardinality("  ':<>: 'ShowType chType  ':<>: 'Text ") is unsupported"
    ':$$: 'Text "Use one of these types:"
    ':$$: 'Text "  ChString"
    ':$$: 'Text "  DateTime"
    ':$$: 'Text "  Nullable(T)"
    )
  ) => IsLowCardinalitySupported chType

instance
  ToChType inputType chType
  =>
  ToChType (LowCardinality inputType) chType where
  toChType :: chType -> LowCardinality inputType
toChType = inputType -> LowCardinality inputType
forall chType. chType -> LowCardinality chType
MkLowCardinality (inputType -> LowCardinality inputType)
-> (chType -> inputType) -> chType -> LowCardinality inputType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. chType -> inputType
forall chType userType.
ToChType chType userType =>
userType -> chType
toChType
  fromChType :: LowCardinality inputType -> chType
fromChType (MkLowCardinality inputType
lc)= forall chType userType.
ToChType chType userType =>
chType -> userType
fromChType @inputType inputType
lc

instance ToQueryPart chType => ToQueryPart (LowCardinality chType)
  where
  toQueryPart :: LowCardinality chType -> Builder
toQueryPart (MkLowCardinality chType
chType) = chType -> Builder
forall chType. ToQueryPart chType => chType -> Builder
toQueryPart chType
chType