Merge pull request #163 from morphismtech/dev-params-oids

parameter  oids
This commit is contained in:
Eitan Chatav 2019-10-28 11:22:12 -07:00 committed by GitHub
commit b63086cdbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 192 additions and 68 deletions

View File

@ -216,8 +216,9 @@ module Squeal.PostgreSQL.Binary
-- * Only
, Only (..)
-- * Oid
, HasOid (..)
, HasAliasedOid (..)
, OidOf (..)
, OidOfParam (..)
, OidOfField (..)
) where
import BinaryParser
@ -231,6 +232,7 @@ import Data.Time
import Data.UUID.Types
import Data.Vector (Vector)
import Data.Word
import Foreign.C.Types (CUInt(CUInt))
import Generics.SOP
import Generics.SOP.Record
import GHC.TypeLits
@ -244,6 +246,7 @@ import qualified Data.Text.Lazy as Lazy (Text)
import qualified Data.Text as Strict (Text)
import qualified Data.Text as Strict.Text
import qualified Data.Vector as Vector
import qualified Database.PostgreSQL.LibPQ as LibPQ
import qualified GHC.Generics as GHC
import qualified PostgreSQL.Binary.Decoding as Decoding
import qualified PostgreSQL.Binary.Encoding as Encoding
@ -309,24 +312,24 @@ instance Aeson.ToJSON x => ToParam (Json x) 'PGjson where
instance Aeson.ToJSON x => ToParam (Jsonb x) 'PGjsonb where
toParam = K . Encoding.jsonb_bytes
. Lazy.ByteString.toStrict . Aeson.encode . getJsonb
instance (ToNullityParam x ty, ty ~ nullity pg, HasOid pg)
instance (ToNullityParam x ty, ty ~ nullity pg, OidOf pg)
=> ToParam (VarArray [x]) ('PGvararray ty) where
toParam = K
. Encoding.array_foldable
(getOid (oidOf @pg)) (unK . toNullityParam @x @ty)
. getVarArray
instance (ToParam x pg, HasOid pg)
instance (ToParam x pg, OidOf pg)
=> ToParam (VarArray (Vector x)) ('PGvararray ('NotNull pg)) where
toParam = K
. Encoding.array_vector (getOid (oidOf @pg)) (unK . toParam @x @pg)
. getVarArray
instance (ToParam x pg, HasOid pg)
instance (ToParam x pg, OidOf pg)
=> ToParam (VarArray (Vector (Maybe x))) ('PGvararray ('Null pg)) where
toParam = K
. Encoding.nullableArray_vector
(getOid (oidOf @pg)) (unK . toParam @x @pg)
. getVarArray
instance (ToFixArray x dims ty, ty ~ nullity pg, HasOid pg)
instance (ToFixArray x dims ty, ty ~ nullity pg, OidOf pg)
=> ToParam (FixArray x) ('PGfixarray dims ty) where
toParam = K . Encoding.array (getOid (oidOf @pg))
. unK . unK . toFixArray @x @dims @ty . getFixArray
@ -353,7 +356,7 @@ instance
( SListI fields
, IsRecord x xs
, AllZip ToField xs fields
, All HasAliasedOid fields
, All OidOfField fields
) => ToParam (Composite x) ('PGcomposite fields) where
toParam =
let
@ -361,7 +364,7 @@ instance
encoders = htrans (Proxy @ToField) toField
composite
:: All HasAliasedOid row
:: All OidOfField row
=> NP (K (Maybe Encoding.Encoding)) row
-> K Encoding.Encoding ('PGcomposite row)
composite fields = K $
@ -378,18 +381,18 @@ instance
int32BE (fromIntegral (lengthSList (Proxy @xs))) <>
let
each
:: HasAliasedOid field
:: OidOfField field
=> K (Maybe Encoding.Encoding) field
-> Encoding.Encoding
each (K field :: K (Maybe Encoding.Encoding) field) =
word32BE (getOid (aliasedOid @field))
word32BE (getOid (oidOfField @field))
<> case field of
Nothing -> int64BE (-1)
Just value ->
int32BE (fromIntegral (builderLength value))
<> value
in
hcfoldMap (Proxy @HasAliasedOid) each fields
hcfoldMap (Proxy @OidOfField) each fields
in
composite . encoders . toRecord . getComposite
@ -398,35 +401,119 @@ instance
--
-- >>> :set -XTypeApplications
-- >>> oidOf @'PGbool
-- Oid {getOid = 16}
class HasOid (ty :: PGType) where oidOf :: Oid
instance HasOid 'PGbool where oidOf = Oid 16
instance HasOid 'PGint2 where oidOf = Oid 21
instance HasOid 'PGint4 where oidOf = Oid 23
instance HasOid 'PGint8 where oidOf = Oid 20
instance HasOid 'PGnumeric where oidOf = Oid 1700
instance HasOid 'PGfloat4 where oidOf = Oid 700
instance HasOid 'PGfloat8 where oidOf = Oid 701
instance HasOid ('PGchar n) where oidOf = Oid 18
instance HasOid ('PGvarchar n) where oidOf = Oid 1043
instance HasOid 'PGtext where oidOf = Oid 25
instance HasOid 'PGbytea where oidOf = Oid 17
instance HasOid 'PGtimestamp where oidOf = Oid 1114
instance HasOid 'PGtimestamptz where oidOf = Oid 1184
instance HasOid 'PGdate where oidOf = Oid 1082
instance HasOid 'PGtime where oidOf = Oid 1083
instance HasOid 'PGtimetz where oidOf = Oid 1266
instance HasOid 'PGinterval where oidOf = Oid 1186
instance HasOid 'PGuuid where oidOf = Oid 2950
instance HasOid 'PGinet where oidOf = Oid 869
instance HasOid 'PGjson where oidOf = Oid 114
instance HasOid 'PGjsonb where oidOf = Oid 3802
-- Oid 16
class OidOf (ty :: PGType) where oidOf :: LibPQ.Oid
instance OidOf 'PGbool where oidOf = LibPQ.Oid 16
instance OidOf ('PGfixarray ns (null 'PGbool)) where oidOf = LibPQ.Oid 1000
instance OidOf ('PGvararray (null 'PGbool)) where oidOf = LibPQ.Oid 1000
instance OidOf 'PGint2 where oidOf = LibPQ.Oid 21
instance OidOf ('PGfixarray ns (null 'PGint2)) where oidOf = LibPQ.Oid 1005
instance OidOf ('PGvararray (null 'PGint2)) where oidOf = LibPQ.Oid 1005
instance OidOf 'PGint4 where oidOf = LibPQ.Oid 23
instance OidOf ('PGfixarray ns (null 'PGint4)) where oidOf = LibPQ.Oid 1007
instance OidOf ('PGvararray (null 'PGint4)) where oidOf = LibPQ.Oid 1007
instance OidOf 'PGint8 where oidOf = LibPQ.Oid 20
instance OidOf ('PGfixarray ns (null 'PGint8)) where oidOf = LibPQ.Oid 1016
instance OidOf ('PGvararray (null 'PGint8)) where oidOf = LibPQ.Oid 1016
instance OidOf 'PGnumeric where oidOf = LibPQ.Oid 1700
instance OidOf ('PGfixarray ns (null 'PGnumeric)) where oidOf = LibPQ.Oid 1231
instance OidOf ('PGvararray (null 'PGnumeric)) where oidOf = LibPQ.Oid 1231
instance OidOf 'PGfloat4 where oidOf = LibPQ.Oid 700
instance OidOf ('PGfixarray ns (null 'PGfloat4)) where oidOf = LibPQ.Oid 1021
instance OidOf ('PGvararray (null 'PGfloat4)) where oidOf = LibPQ.Oid 1021
instance OidOf 'PGfloat8 where oidOf = LibPQ.Oid 701
instance OidOf ('PGfixarray ns (null 'PGfloat8)) where oidOf = LibPQ.Oid 1022
instance OidOf ('PGvararray (null 'PGfloat8)) where oidOf = LibPQ.Oid 1022
instance OidOf 'PGmoney where oidOf = LibPQ.Oid 790
instance OidOf ('PGfixarray ns (null 'PGmoney)) where oidOf = LibPQ.Oid 791
instance OidOf ('PGvararray (null 'PGmoney)) where oidOf = LibPQ.Oid 791
instance OidOf ('PGchar n) where oidOf = LibPQ.Oid 18
instance OidOf ('PGfixarray ns (null ('PGchar n))) where oidOf = LibPQ.Oid 1002
instance OidOf ('PGvararray (null ('PGchar n))) where oidOf = LibPQ.Oid 1002
instance OidOf ('PGvarchar n) where oidOf = LibPQ.Oid 1043
instance OidOf ('PGfixarray ns (null ('PGvarchar n))) where oidOf = LibPQ.Oid 1015
instance OidOf ('PGvararray (null ('PGvarchar n))) where oidOf = LibPQ.Oid 1015
instance OidOf 'PGtext where oidOf = LibPQ.Oid 25
instance OidOf ('PGfixarray ns (null 'PGtext)) where oidOf = LibPQ.Oid 1009
instance OidOf ('PGvararray (null 'PGtext)) where oidOf = LibPQ.Oid 1009
instance OidOf 'PGbytea where oidOf = LibPQ.Oid 17
instance OidOf ('PGfixarray ns (null 'PGbytea)) where oidOf = LibPQ.Oid 1001
instance OidOf ('PGvararray (null 'PGbytea)) where oidOf = LibPQ.Oid 1001
instance OidOf 'PGtimestamp where oidOf = LibPQ.Oid 1114
instance OidOf ('PGfixarray ns (null 'PGtimestamp)) where oidOf = LibPQ.Oid 1115
instance OidOf ('PGvararray (null 'PGtimestamp)) where oidOf = LibPQ.Oid 1115
instance OidOf 'PGtimestamptz where oidOf = LibPQ.Oid 1184
instance OidOf ('PGfixarray ns (null 'PGtimestamptz)) where oidOf = LibPQ.Oid 1185
instance OidOf ('PGvararray (null 'PGtimestamptz)) where oidOf = LibPQ.Oid 1185
instance OidOf 'PGdate where oidOf = LibPQ.Oid 1082
instance OidOf ('PGfixarray ns (null 'PGdate)) where oidOf = LibPQ.Oid 1182
instance OidOf ('PGvararray (null 'PGdate)) where oidOf = LibPQ.Oid 1182
instance OidOf 'PGtime where oidOf = LibPQ.Oid 1083
instance OidOf ('PGfixarray ns (null 'PGtime)) where oidOf = LibPQ.Oid 1183
instance OidOf ('PGvararray (null 'PGtime)) where oidOf = LibPQ.Oid 1183
instance OidOf 'PGtimetz where oidOf = LibPQ.Oid 1266
instance OidOf ('PGfixarray ns (null 'PGtimetz)) where oidOf = LibPQ.Oid 1270
instance OidOf ('PGvararray (null 'PGtimetz)) where oidOf = LibPQ.Oid 1270
instance OidOf 'PGinterval where oidOf = LibPQ.Oid 1186
instance OidOf ('PGfixarray ns (null 'PGinterval)) where oidOf = LibPQ.Oid 1187
instance OidOf ('PGvararray (null 'PGinterval)) where oidOf = LibPQ.Oid 1187
instance OidOf 'PGuuid where oidOf = LibPQ.Oid 2950
instance OidOf ('PGfixarray ns (null 'PGuuid)) where oidOf = LibPQ.Oid 2951
instance OidOf ('PGvararray (null 'PGuuid)) where oidOf = LibPQ.Oid 2951
instance OidOf 'PGinet where oidOf = LibPQ.Oid 869
instance OidOf ('PGfixarray ns (null 'PGinet)) where oidOf = LibPQ.Oid 1041
instance OidOf ('PGvararray (null 'PGinet)) where oidOf = LibPQ.Oid 1041
instance OidOf 'PGjson where oidOf = LibPQ.Oid 114
instance OidOf ('PGfixarray ns (null 'PGjson)) where oidOf = LibPQ.Oid 199
instance OidOf ('PGvararray (null 'PGjson)) where oidOf = LibPQ.Oid 199
instance OidOf 'PGjsonb where oidOf = LibPQ.Oid 3802
instance OidOf ('PGfixarray ns (null 'PGjsonb)) where oidOf = LibPQ.Oid 3807
instance OidOf ('PGvararray (null 'PGjsonb)) where oidOf = LibPQ.Oid 3807
instance OidOf 'PGtsvector where oidOf = LibPQ.Oid 3614
instance OidOf ('PGfixarray ns (null 'PGtsvector)) where oidOf = LibPQ.Oid 3643
instance OidOf ('PGvararray (null 'PGtsvector)) where oidOf = LibPQ.Oid 3643
instance OidOf 'PGtsquery where oidOf = LibPQ.Oid 3615
instance OidOf ('PGfixarray ns (null 'PGtsquery)) where oidOf = LibPQ.Oid 3645
instance OidOf ('PGvararray (null 'PGtsquery)) where oidOf = LibPQ.Oid 3645
instance OidOf 'PGoid where oidOf = LibPQ.Oid 26
instance OidOf ('PGfixarray ns (null 'PGoid)) where oidOf = LibPQ.Oid 1028
instance OidOf ('PGvararray (null 'PGoid)) where oidOf = LibPQ.Oid 1028
instance OidOf ('PGrange 'PGint4) where oidOf = LibPQ.Oid 3904
instance OidOf ('PGfixarray ns (null ('PGrange 'PGint4))) where oidOf = LibPQ.Oid 3905
instance OidOf ('PGvararray (null ('PGrange 'PGint4))) where oidOf = LibPQ.Oid 3905
instance OidOf ('PGrange 'PGint8) where oidOf = LibPQ.Oid 3926
instance OidOf ('PGfixarray ns (null ('PGrange 'PGint8))) where oidOf = LibPQ.Oid 3927
instance OidOf ('PGvararray (null ('PGrange 'PGint8))) where oidOf = LibPQ.Oid 3927
instance OidOf ('PGrange 'PGnumeric) where oidOf = LibPQ.Oid 3906
instance OidOf ('PGfixarray ns (null ('PGrange 'PGnumeric))) where oidOf = LibPQ.Oid 3907
instance OidOf ('PGvararray (null ('PGrange 'PGnumeric))) where oidOf = LibPQ.Oid 3907
instance OidOf ('PGrange 'PGtimestamp) where oidOf = LibPQ.Oid 3908
instance OidOf ('PGfixarray ns (null ('PGrange 'PGtimestamp))) where oidOf = LibPQ.Oid 3909
instance OidOf ('PGvararray (null ('PGrange 'PGtimestamp))) where oidOf = LibPQ.Oid 3909
instance OidOf ('PGrange 'PGtimestamptz) where oidOf = LibPQ.Oid 3910
instance OidOf ('PGfixarray ns (null ('PGrange 'PGtimestamptz))) where oidOf = LibPQ.Oid 3911
instance OidOf ('PGvararray (null ('PGrange 'PGtimestamptz))) where oidOf = LibPQ.Oid 3911
instance OidOf ('PGrange 'PGdate) where oidOf = LibPQ.Oid 3912
instance OidOf ('PGfixarray ns (null ('PGrange 'PGdate))) where oidOf = LibPQ.Oid 3913
instance OidOf ('PGvararray (null ('PGrange 'PGdate))) where oidOf = LibPQ.Oid 3913
instance {-# OVERLAPPABLE #-} OidOf ('PGrange ty) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGfixarray ns (null ('PGrange ty))) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGvararray (null ('PGrange ty))) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGcomposite row) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGfixarray ns (null ('PGcomposite row))) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGvararray (null ('PGcomposite row))) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGenum labels) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGfixarray ns (null ('PGenum labels))) where oidOf = LibPQ.invalidOid
instance {-# OVERLAPPABLE #-} OidOf ('PGvararray (null ('PGenum labels))) where oidOf = LibPQ.invalidOid
-- | Lifts a `HasOid` constraint to a field.
class HasAliasedOid (field :: (Symbol, NullityType)) where
aliasedOid :: Oid
instance HasOid ty => HasAliasedOid (alias ::: nullity ty) where
aliasedOid = oidOf @ty
class OidOfParam (ty :: NullityType) where oidOfParam :: Oid
instance OidOf ty => OidOfParam (null ty) where oidOfParam = oidOf @ty
-- | Lifts a `OidOf` constraint to a field.
class OidOfField (field :: (Symbol, NullityType)) where
oidOfField :: Oid
instance OidOf ty => OidOfField (alias ::: nullity ty) where
oidOfField = oidOf @ty
-- | A `ToNullityParam` constraint gives an encoding of a Haskell `Type` into
-- into the binary format of a PostgreSQL `NullityType`.
@ -756,3 +843,6 @@ replicateMN
=> m x -> m (NP I xs)
replicateMN mx = hsequence' $
hcpure (Proxy :: Proxy ((~) x)) (Comp (I <$> mx))
getOid :: LibPQ.Oid -> Word32
getOid (LibPQ.Oid (CUInt oid)) = oid

View File

@ -340,6 +340,12 @@ instance (SOP.All KnownNat dims, PGTyped schemas ty)
instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
instance PGTyped schemas (null 'PGoid) where pgtype = oid
instance PGTyped schemas (null ('PGrange 'PGint4)) where pgtype = int4range
instance PGTyped schemas (null ('PGrange 'PGint8)) where pgtype = int8range
instance PGTyped schemas (null ('PGrange 'PGnumeric)) where pgtype = numrange
instance PGTyped schemas (null ('PGrange 'PGtimestamp)) where pgtype = tsrange
instance PGTyped schemas (null ('PGrange 'PGtimestamptz)) where pgtype = tstzrange
instance PGTyped schemas (null ('PGrange 'PGdate)) where pgtype = daterange
-- | Lift `PGTyped` to a field
class FieldTyped schemas ty where

View File

@ -47,7 +47,7 @@ module Squeal.PostgreSQL.PG
, Enumerated (..)
, VarArray (..)
, FixArray (..)
, Oid (..)
, LibPQ.Oid (..)
-- * Type families
, LabelsPG
, DimPG
@ -66,7 +66,6 @@ import Data.Int (Int16, Int32, Int64)
import Data.Scientific (Scientific)
import Data.Time (Day, DiffTime, LocalTime, TimeOfDay, TimeZone, UTCTime)
import Data.Vector (Vector)
import Data.Word (Word32)
import Data.UUID.Types (UUID)
import GHC.TypeLits
import Network.IP.Addr (NetAddr, IP)
@ -75,6 +74,7 @@ import qualified Data.ByteString.Lazy as Lazy (ByteString)
import qualified Data.ByteString as Strict (ByteString)
import qualified Data.Text.Lazy as Lazy (Text)
import qualified Data.Text as Strict (Text)
import qualified Database.PostgreSQL.LibPQ as LibPQ
import qualified GHC.Generics as GHC
import qualified Generics.SOP as SOP
import qualified Generics.SOP.Record as SOP
@ -108,7 +108,7 @@ type instance PG Int32 = 'PGint4
-- | `PGint8`
type instance PG Int64 = 'PGint8
-- | `PGint2`
type instance PG Oid = 'PGoid
type instance PG LibPQ.Oid = 'PGoid
-- | `PGnumeric`
type instance PG Scientific = 'PGnumeric
-- | `PGfloat4`
@ -386,10 +386,3 @@ newtype FixArray arr = FixArray {getFixArray :: arr}
deriving anyclass (SOP.HasDatatypeInfo, SOP.Generic)
-- | `PGfixarray` @(@`DimPG` @hask) (@`FixPG` @hask)@
type instance PG (FixArray hask) = 'PGfixarray (DimPG hask) (FixPG hask)
{- | Object identifiers (`Oid`s) are used internally by PostgreSQL
as primary keys for various system tables.
-}
newtype Oid = Oid { getOid :: Word32 }
deriving stock (Eq, Ord, Show, Read, GHC.Generic)
deriving anyclass (SOP.HasDatatypeInfo, SOP.Generic)

View File

@ -78,6 +78,7 @@ import UnliftIO (MonadUnliftIO (..), bracket, catch, handle, try)
import Data.ByteString (ByteString)
import Data.Foldable
import Data.Function ((&))
import Data.Functor ((<&>))
import Data.Kind
import Data.Text (pack, Text)
import Data.Traversable
@ -86,6 +87,7 @@ import PostgreSQL.Binary.Encoding (encodingBytes)
import qualified Control.Monad.Fail as Fail
import qualified Database.PostgreSQL.LibPQ as LibPQ
import qualified PostgreSQL.Binary.Encoding as Encoding
import Squeal.PostgreSQL.Binary
import Squeal.PostgreSQL.Definition
@ -315,13 +317,13 @@ a default instance.
-}
class Monad pq => MonadPQ schemas pq | pq -> schemas where
manipulateParams
:: ToParams x params
:: (ToParams x params, All OidOfParam params)
=> Manipulation '[] schemas params ys
-- ^ `insertInto`, `update` or `deleteFrom`
-> x -> pq (K LibPQ.Result ys)
default manipulateParams
:: (MonadTrans t, MonadPQ schemas pq1, pq ~ t pq1)
=> ToParams x params
=> (ToParams x params, All OidOfParam params)
=> Manipulation '[] schemas params ys
-- ^ `insertInto`, `update` or `deleteFrom`
-> x -> pq (K LibPQ.Result ys)
@ -329,7 +331,7 @@ class Monad pq => MonadPQ schemas pq | pq -> schemas where
manipulateParams manipulation params
manipulateParams_
:: ToParams x params
:: (ToParams x params, All OidOfParam params)
=> Manipulation '[] schemas params '[]
-- ^ `insertInto`, `update` or `deleteFrom`
-> x -> pq ()
@ -342,7 +344,7 @@ class Monad pq => MonadPQ schemas pq | pq -> schemas where
manipulate_ = void . manipulate
runQueryParams
:: ToParams x params
:: (ToParams x params, All OidOfParam params)
=> Query '[] '[] schemas params ys
-- ^ `select` and friends
-> x -> pq (K LibPQ.Result ys)
@ -355,19 +357,19 @@ class Monad pq => MonadPQ schemas pq | pq -> schemas where
runQuery q = runQueryParams q ()
traversePrepared
:: (ToParams x params, Traversable list)
:: (ToParams x params, Traversable list, All OidOfParam params)
=> Manipulation '[] schemas params ys
-- ^ `insertInto`, `update`, or `deleteFrom`, and friends
-> list x -> pq (list (K LibPQ.Result ys))
default traversePrepared
:: (MonadTrans t, MonadPQ schemas pq1, pq ~ t pq1)
=> (ToParams x params, Traversable list)
=> (ToParams x params, Traversable list, All OidOfParam params)
=> Manipulation '[] schemas params ys -> list x -> pq (list (K LibPQ.Result ys))
traversePrepared manipulation params = lift $
traversePrepared manipulation params
forPrepared
:: (ToParams x params, Traversable list)
:: (ToParams x params, Traversable list, All OidOfParam params)
=> list x
-> Manipulation '[] schemas params ys
-- ^ `insertInto`, `update` or `deleteFrom`
@ -375,13 +377,13 @@ class Monad pq => MonadPQ schemas pq | pq -> schemas where
forPrepared = flip traversePrepared
traversePrepared_
:: (ToParams x params, Foldable list)
:: (ToParams x params, Foldable list, All OidOfParam params)
=> Manipulation '[] schemas params '[]
-- ^ `insertInto`, `update` or `deleteFrom`
-> list x -> pq ()
default traversePrepared_
:: (MonadTrans t, MonadPQ schemas pq1, pq ~ t pq1)
=> (ToParams x params, Foldable list)
=> (ToParams x params, Foldable list, All OidOfParam params)
=> Manipulation '[] schemas params '[]
-- ^ `insertInto`, `update` or `deleteFrom`
-> list x -> pq ()
@ -389,7 +391,7 @@ class Monad pq => MonadPQ schemas pq | pq -> schemas where
traversePrepared_ manipulation params
forPrepared_
:: (ToParams x params, Foldable list)
:: (ToParams x params, Foldable list, All OidOfParam params)
=> list x
-> Manipulation '[] schemas params '[]
-- ^ `insertInto`, `update` or `deleteFrom`
@ -409,9 +411,17 @@ instance (MonadIO io, schemas0 ~ schemas, schemas1 ~ schemas)
(UnsafeManipulation q :: Manipulation '[] schemas ps ys) (params :: x) =
PQ $ \ (K conn) -> do
let
toParam' encoding =
(LibPQ.invalidOid, encodingBytes encoding, LibPQ.Binary)
params' = fmap (fmap toParam') (hcollapse (toParams @x @ps params))
paramSet
:: forall param. OidOfParam param
=> K (Maybe Encoding.Encoding) param
-> K (Maybe (LibPQ.Oid, ByteString, LibPQ.Format)) param
paramSet (K maybeEncoding) = K $
maybeEncoding <&> \encoding ->
(oidOfParam @param, encodingBytes encoding, LibPQ.Binary)
params'
= hcollapse
. hcmap (Proxy @OidOfParam) paramSet
$ toParams @x @ps params
q' = q <> ";"
resultMaybe <- liftIO $ LibPQ.execParams conn q' params' LibPQ.Binary
case resultMaybe of
@ -424,8 +434,15 @@ instance (MonadIO io, schemas0 ~ schemas, schemas1 ~ schemas)
traversePrepared
(UnsafeManipulation q :: Manipulation '[] schemas xs ys) (list :: list x) =
PQ $ \ (K conn) -> liftIO $ do
let temp = "temporary_statement"
prepResultMaybe <- LibPQ.prepare conn temp q Nothing
let
temp = "temporary_statement"
paramOid :: forall p. OidOfParam p => K LibPQ.Oid p
paramOid = K (oidOfParam @p)
paramOids :: NP (K LibPQ.Oid) xs
paramOids = hcpure (Proxy @OidOfParam) paramOid
paramOids' :: [LibPQ.Oid]
paramOids' = hcollapse paramOids
prepResultMaybe <- LibPQ.prepare conn temp q (Just paramOids')
case prepResultMaybe of
Nothing -> throw $ ResultException
"traversePrepared: LibPQ.prepare returned no results"
@ -451,8 +468,15 @@ instance (MonadIO io, schemas0 ~ schemas, schemas1 ~ schemas)
traversePrepared_
(UnsafeManipulation q :: Manipulation '[] schemas xs '[]) (list :: list x) =
PQ $ \ (K conn) -> liftIO $ do
let temp = "temporary_statement"
prepResultMaybe <- LibPQ.prepare conn temp q Nothing
let
temp = "temporary_statement"
paramOid :: forall p. OidOfParam p => K LibPQ.Oid p
paramOid = K (oidOfParam @p)
paramOids :: NP (K LibPQ.Oid) xs
paramOids = hcpure (Proxy @OidOfParam) paramOid
paramOids' :: [LibPQ.Oid]
paramOids' = hcollapse paramOids
prepResultMaybe <- LibPQ.prepare conn temp q (Just paramOids')
case prepResultMaybe of
Nothing -> throw $ ResultException
"traversePrepared_: LibPQ.prepare returned no results"

View File

@ -92,14 +92,14 @@ roundtrips = Group "roundtrips"
-- genTimeWithZone = (,) <$> genTimeOfDay <*> genTimeZone
roundtrip
:: (ToParam x ty, FromValue ty x, Show x, Eq x)
:: (OidOf ty, ToParam x ty, FromValue ty x, Show x, Eq x)
=> TypeExpression schemas ('NotNull ty)
-> Gen x
-> (PropertyName, Property)
roundtrip = roundtripOn id
roundtripOn
:: (ToParam x ty, FromValue ty x, Show x, Eq x)
:: (OidOf ty, ToParam x ty, FromValue ty x, Show x, Eq x)
=> (x -> x)
-> TypeExpression schemas ('NotNull ty)
-> Gen x

View File

@ -123,3 +123,14 @@ spec = before_ setupDB . after_ dropDB $ do
getRows =<< runQuery query
(fromOnly <$> rangesOut :: [Range Int32]) `shouldBe`
[ atLeast 3, 3 <=..< 5, Empty, whole ]
describe "Parameters" $ do
it "should run queries that don't reference all their parameters" $ do
out <- withConnection connectionString $ do
let
query :: Query_ (Public '[]) (Char,Int32) (Only Int32)
query = values_ (param @2 `as` #fromOnly)
firstRow =<< runQueryParams query ('a', 3 :: Int32)
(fromOnly <$> out :: Maybe Int32) `shouldBe` Just 3