module Spark.Core.Internal.RowGenerics(
ToSQL,
valueToCell,
) where
import GHC.Generics
import qualified Data.Vector as V
import Data.Text(pack)
import Spark.Core.Internal.RowStructures
import Spark.Core.Internal.Utilities
data CurrentBuffer =
ConsData ![Cell]
| BuiltCell !Cell deriving (Show)
_cellOrError :: CurrentBuffer -> Cell
_cellOrError (BuiltCell cell) = cell
_cellOrError x = let msg = "Expected built cell, received " ++ show x in
failure (pack msg)
class ToSQL a where
_valueToCell :: a -> Cell
default _valueToCell :: (Generic a, GToSQL (Rep a)) => a -> Cell
_valueToCell !x = _g2cell (from x)
valueToCell :: (ToSQL a) => a -> Cell
valueToCell = _valueToCell
instance ToSQL a => ToSQL (Maybe a) where
_valueToCell (Just x) = _valueToCell x
_valueToCell Nothing = Empty
instance ToSQL Int where
_valueToCell = IntElement
class GToSQL r where
_g2buffer :: r a -> CurrentBuffer
_g2cell :: r a -> Cell
_g2cell = _cellOrError . _g2buffer
instance GToSQL U1 where
_g2buffer U1 = failure $ pack "GToSQL UI called"
instance (GToSQL a, GToSQL b) => GToSQL (a :*: b) where
_g2buffer (a :*: b) = case (_g2buffer a, _g2buffer b) of
(ConsData l1, ConsData l2) -> ConsData (l1 ++ l2)
(y1, y2) -> failure $ pack $ "GToSQL (a :*: b): Expected buffers, received " ++ show y1 ++ " and " ++ show y2
instance (GToSQL a, GToSQL b) => GToSQL (a :+: b) where
_g2buffer (L1 x) = _g2buffer x
_g2buffer (R1 x) = let !y = _g2buffer x in y
instance (GToSQL a, Constructor c) => GToSQL (M1 C c a) where
_g2buffer (M1 x) = let !y = _g2buffer x in y
instance (GToSQL a, Selector c) => GToSQL (M1 S c a) where
_g2buffer (M1 x) = let !y = ConsData [_g2cell x] in y
instance (GToSQL a, Datatype c) => GToSQL (M1 D c a) where
_g2buffer (M1 x) =
case _g2buffer x of
ConsData cs -> BuiltCell $ RowArray (V.fromList cs)
BuiltCell cell -> BuiltCell cell
instance (ToSQL a) => GToSQL (K1 i a) where
_g2buffer (K1 x) = let !y = _valueToCell x in BuiltCell y