-- | -- Module : Hpgsql -- Description : A pure Haskell PostgreSQL driver (no libpq) with pipelines, prepared statements, streaming, thread safety and interruption safety. -- -- Hpgsql is a PostgreSQL driver written entirely in Haskell, with no bindings to @libpq@. -- It communicates with the database using the PostgreSQL wire protocol directly. -- -- = Quick start -- -- Connect to the database and run a simple query: -- -- > {-# LANGUAGE QuasiQuotes #-} -- > import Hpgsql -- > import Hpgsql.Connection (withConnection, ConnectionString(..)) -- > import Hpgsql.Query (sql) -- > -- > main :: IO () -- > main = do -- > let connstr = ConnectionString -- > { hostname = "localhost" -- > , port = 5432 -- > , user = "postgres" -- > , password = "" -- > , database = "mydb" -- > , options = "" -- > } -- > -- Connect with a 10-second timeout -- > withConnection connstr 10 $ \conn -> do -- > rows <- query conn [sql|SELECT 1 + 1|] -- > print (rows :: [Only Int]) -- > -- [Only {fromOnly = 2}] -- -- = Building queries -- -- Use the @[sql|...|]@ quasiquoter from "Hpgsql.Query" to build queries. Interpolate Haskell -- values with @#{}@: -- -- > let name = "Alice" :: Text -- > rows <- query conn [sql|SELECT id, email FROM users WHERE name = #{name}|] -- > print (rows :: [(Int, Text)]) -- -- Values interpolated with @#{}@ are sent as query parameters, so they are safe from SQL injection. -- -- To embed a 'Query' fragment (e.g. an identifier or a sub-query), use @^{}@: -- -- > let tableName = escapeIdentifier "users" -- > rows <- query conn [sql|SELECT * FROM ^{tableName}|] -- -- You can also use 'Hpgsql.Query.mkQuery' with dollar-numbered query arguments: -- -- > query conn (mkQuery "SELECT * FROM users WHERE age BETWEEN $1 AND $2" (18 :: Int, 60 :: Int)) -- -- And finally, you can use the @[sqlPrep|...|]@ quasiquoter to build prepared statements. -- -- = Fetching results -- -- * 'query' returns all rows as a list. -- * 'queryS' returns all rows as a Stream, streaming directly from the socket (without cursors). -- * 'query1' returns exactly one row, throwing if zero or more than one row is returned. -- * 'queryMay' returns zero or one row, throwing if more than one is returned. -- * 'execute' runs a statement and returns the count of affected rows. -- * 'execute_' runs a statement and discards the result. -- -- All these methods have equivalents in "Hpgsql.Pipeline" that can be composed together -- to reduce the number of round-trips. -- -- = Encoders and decoders -- -- To define your own encoder and decoder instances, take a look at "Hpgsql.Encoding". -- -- = Handling errors -- -- - Hpgsql is interruption-safe (with one exception for COPY inside transactions; see "Hpgsql.Copy"), so a query can be interrupted by asynchronous exceptions and you should still be able to run new queries on the same connection without any other side-effects. Naturally, it is up to you to determine which queries ran or not to completion, since they might have side-effects. -- - Hpgsql will throw either `PostgresError` or `IrrecoverableHpgsqlError`, and: -- - If you receive a `IrrecoverableHpgsqlError`, Hpgsql makes no promises about which statements ran to completion and what connection state is, and you should `closeForcefully` the connection without running any other queries. These errors should only be thrown for "obvious" developer mistakes from which usually there would be no way to proceed, anyway. -- - If you receive a `PostgresError` exception, postgres and Hpgsql's states are synced and you can issue new queries afterwards. -- -- = What's in this module -- -- This module re-exports some of the essentials: querying and the core types. -- We recommend importing from this module instead of others whenever possible. -- For more functionality, see: -- -- * "Hpgsql.Connection" for connecting and connection state resetting. -- * "Hpgsql.Copy" for @COPY@ protocol support. -- * "Hpgsql.Pipeline" for building pipelines of queries. -- * "Hpgsql.Query" for the @sql@ and @sqlPrep@ quasiquoters, and query-building helpers. -- * "Hpgsql.Transaction" for transaction management. -- * "Hpgsql.Types" for extra types that might be useful. -- * "Hpgsql.Cancellation" for cancelling active queries. module Hpgsql ( -- * Query query, queryWith, queryMWith, queryS, querySWith, querySMWith, query1, query1With, queryMay, queryMayWith, execute, execute_, -- * Useful re-exports HPgConnection, -- Do not export constructor PostgresError (..), IrrecoverableHpgsqlError (..), ErrorDetail (..), ) where import Hpgsql.Internal import Hpgsql.InternalTypes (ErrorDetail (..), HPgConnection, IrrecoverableHpgsqlError (..), PostgresError (..))