Skip to content

Commit a3c0dd2

Browse files
committed
Add libPQVersion function
1 parent 1be72e1 commit a3c0dd2

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

postgresql-libpq.cabal

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ Library
3636
Build-depends: base >= 4 && < 5
3737
, bytestring
3838

39+
if !os(windows)
40+
Build-depends: unix
41+
42+
if os(windows)
43+
Build-depends: Win32
44+
45+
3946
GHC-Options: -Wall
4047
if flag(use-pkg-config)
4148
Pkgconfig-depends: libpq

src/Database/PostgreSQL/LibPQ.hsc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ module Database.PostgreSQL.LibPQ
7878
, parameterStatus
7979
, protocolVersion
8080
, serverVersion
81+
, libPQVersion
8182
, errorMessage
8283
, socket
8384
, backendPID
@@ -254,6 +255,14 @@ import qualified Control.Exception
254255
mask_ = Control.Exception.block
255256
#endif
256257

258+
import Control.Exception (try, IOException)
259+
260+
#ifndef mingw32_HOST_OS
261+
import System.Posix.DynamicLinker
262+
#else
263+
import System.Win32.DLL
264+
#endif
265+
257266
-- $dbconn
258267
-- The following functions deal with making a connection to a
259268
-- PostgreSQL backend server. An application program can have several
@@ -632,6 +641,30 @@ serverVersion :: Connection
632641
serverVersion connection =
633642
fmap fromIntegral $ withConn connection c_PQserverVersion
634643

644+
-- | Return the version of libpq that is being used.
645+
--
646+
-- The result of this function can be used to determine, at
647+
-- run time, if specific functionality is available in the currently
648+
-- loaded version of libpq. The function can be used, for example,
649+
-- to determine which connection options are available for
650+
-- PQconnectdb or if the hex bytea output added in PostgreSQL 9.0 is supported.
651+
--
652+
-- This function appeared in PostgreSQL version 9.1, so
653+
-- it cannot be used to detect required functionality in earlier
654+
-- versions, since linking to it will create a link dependency
655+
-- on version 9.1.
656+
libPQVersion :: IO Int
657+
libPQVersion = do
658+
#ifndef mingw32_HOST_OS
659+
dl <- dlopen "libpq.so" [RTLD_LAZY]
660+
res <- try (dlsym dl "PQlibVersion") :: IO (Either IOException (FunPtr Int))
661+
#else
662+
dl <- loadLibrary "LIBPQ.DLL"
663+
res <- try (castPtrToFunPtr `fmap` getProcAddress dl "PQlibVersion") :: IO (Either IOException (FunPtr Int))
664+
#endif
665+
case res of
666+
Left _ -> error "libPQVersion is not supported for libpq < 9.1"
667+
Right funPtr -> pure $ mkLibPQVersion funPtr
635668

636669
-- | Returns the error message most recently generated by an operation
637670
-- on the connection.
@@ -2392,6 +2425,9 @@ foreign import ccall unsafe "libpq-fe.h PQprotocolVersion"
23922425
foreign import ccall unsafe "libpq-fe.h PQserverVersion"
23932426
c_PQserverVersion :: Ptr PGconn -> IO CInt
23942427

2428+
foreign import ccall "dynamic"
2429+
mkLibPQVersion :: FunPtr Int -> Int
2430+
23952431
foreign import ccall unsafe "libpq-fe.h PQsocket"
23962432
c_PQsocket :: Ptr PGconn -> IO CInt
23972433

0 commit comments

Comments
 (0)