51 lines
1.5 KiB
Haskell
51 lines
1.5 KiB
Haskell
{-# LANGUAGE FlexibleInstances #-}
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
module Database.PostgreSQL.Opium.ToField
|
|
( ToField (..)
|
|
) where
|
|
|
|
import Data.Bits (Bits (..))
|
|
import Data.ByteString (ByteString)
|
|
import Data.List (singleton)
|
|
import Data.Text (Text)
|
|
import Data.Word (Word32)
|
|
import Database.PostgreSQL.LibPQ (Format (..), Oid)
|
|
import Unsafe.Coerce (unsafeCoerce)
|
|
|
|
import qualified Data.ByteString as BS
|
|
import qualified Data.Text as Text
|
|
import qualified Data.Text.Encoding as Encoding
|
|
import qualified Database.PostgreSQL.Opium.Oid as Oid
|
|
|
|
class ToField a where
|
|
toField :: a -> Maybe (Oid, ByteString, Format)
|
|
|
|
instance ToField ByteString where
|
|
toField x = Just (Oid.bytea, x, Binary)
|
|
|
|
instance ToField Text where
|
|
toField x = Just (Oid.text, Encoding.encodeUtf8 x, Binary)
|
|
|
|
instance ToField String where
|
|
toField = toField . Text.pack
|
|
|
|
instance ToField Char where
|
|
toField = toField . singleton
|
|
|
|
-- Potentially slow, but good enough for now
|
|
encodeBigEndian :: (Integral a, Bits a) => Int -> a -> ByteString
|
|
encodeBigEndian n = BS.pack . go [] n
|
|
where
|
|
go acc 0 _ = acc
|
|
go acc i x = go (fromIntegral (x .&. 0xff) : acc) (i - 1) (x `shiftR` 8)
|
|
|
|
instance ToField Int where
|
|
toField x = Just (Oid.bigint, encodeBigEndian 8 x, Binary)
|
|
|
|
instance ToField Float where
|
|
toField x = Just (Oid.real, encodeBigEndian @Word32 4 $ unsafeCoerce x, Binary)
|
|
|
|
instance ToField Double where
|
|
toField x = Just (Oid.doublePrecision, encodeBigEndian @Word 8 $ unsafeCoerce x, Binary)
|