module PostgreSQLBinary.Array where
import PostgreSQLBinary.Prelude hiding (Data)
type Data = ([Dimension], [Value], Bool, Word32)
type Dimension = (Word32, Word32)
type Value = Maybe ByteString
asSingleton :: Data -> Maybe Value
asSingleton (dimensions, elements, nulls, oid) =
if null dimensions
then case elements of
[x] -> return x
l -> $bug $ "Unexpected amount of elements: " <> show l
else mzero
fromListUnsafe :: [Data] -> Data
fromListUnsafe list =
case list of
(dimensions, values, nulls, oid) : tail ->
((fromIntegral $ length list, 1) : dimensions, values <> foldMap valuesOf tail, nulls, oid)
where
valuesOf (_, x, _, _) = x
_ ->
error "Empty list"
fromSingleton :: Value -> Bool -> Word32 -> Data
fromSingleton value nullable oid =
([], [value], nullable, oid)
elements :: Data -> [Data]
elements (dimensions, values, nulls, oid) =
do
subvalues <- slice values
return (subdimensions, subvalues, nulls, oid)
where
((width, lowerBound), subdimensions) =
case dimensions of
h : t -> (h, t)
_ -> ((0, 1), [])
chunkSize =
if null subdimensions
then 1
else product $ map dimensionWidth $ subdimensions
where
dimensionWidth (x, _) = fromIntegral x
slice =
foldr (\f g l -> case f l of (a, b) -> a : g b) (const mzero) $
replicate (fromIntegral width) (splitAt chunkSize)