-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | High-level SQLite client.
--
-- High-level SQLite client.
@package sq
@version 0.0.1
-- | High-level SQLite client library
--
-- ⚠️ This is an early preview release of this library. Use at your
-- own risk.
--
--
-- import qualified Sq
--
--
-- Things currently supported:
--
--
-- - Type-safe encoding of SQL query parameters and columns
-- (Encode, Input).
-- - Type-safe decoding of SQL output rows and columns
-- (Decode, Output).
-- - Type-safe concurrent connections with read and write
-- database access (Pool).
-- - Type-safe STM-like transactional interactions with
-- the database, including retry-like, TVar-like, and
-- catchSTM-like tools (Transactional, retry,
-- Ref).
-- - Type-safe distinction between Read-only and
-- read-Write things.
-- - Type-safe streaming and interleaving of IO with
-- output rows (streamIO, foldIO).
-- - Type-safe resource management (via Acquire, see
-- new, with, uith).
-- - Savepoints.
-- - A lot of logging.
--
--
-- Things not supported yet:
--
--
-- - Type-safe SQL.
-- - Manual and automatic migrations solution.
-- - Probably other things.
--
--
-- If you have questions or suggestions, just say so at
-- https://github.com/k0001/hs-sq/issues.
--
-- ⚠️ This is an early preview release of this library. Use at your
-- own risk.
module Sq
-- |
-- - A SQL statement taking a value i as input and producing
-- rows of o values as output.
-- - s indicates whether the statement is Read-only or
-- read-Write.
-- - Construct with readStatement or writeStatement.
--
data Statement (s :: Mode) i o
-- | Construct a Read-only Statement.
--
-- WARNING: This library doesn't yet provide a safe way to
-- construct Statements. You can potentially write anything in
-- your SQL string. Don't do that.
--
--
-- - The SQL must be read-only.
-- - The SQL must contain a single statement.
-- - The SQL must not contain any transaction nor savepoint
-- management statements.
--
readStatement :: Input i -> Output o -> SQL -> Statement 'Read i o
-- | Construct a Statement that can only be executed as part of a
-- Write Transaction.
--
-- WARNING: This library doesn't yet provide a safe way to
-- construct Statements. You can potentially write anything in
-- your SQL string. Don't do that.
--
--
-- - The SQL must contain a single statement.
-- - The SQL must not contain any transaction nor savepoint
-- management statements.
--
writeStatement :: Input i -> Output o -> SQL -> Statement 'Write i o
-- | Raw SQL string. Completely unchecked.
data SQL
-- | A QuasiQuoter for raw SQL strings.
--
-- WARNING: This doesn't check the validity of the SQL. It is
-- offered simply because writing multi-line strings in Haskell is
-- otherwise very annoying.
sql :: QuasiQuoter
-- | How to encode all the input to a single Statement.
--
--
data Input i
-- | Encode a single input parameter. The value will be reachable from the
-- SQL query through the specified Name, with a
-- $ prefix.
--
--
-- writeStatement
-- (encode "foo" encodeDefault)
-- mempty
-- "INSERT INTO t (a) VALUES ($foo)"
-- :: (EncodeDefault x)
-- => Statement Write x ()
--
--
-- Note that by design, this library doesn't support positional
-- Input parameters. You must always pick a Name.
--
-- Multiple Inputs can be composed with Contravariant,
-- Divisible, Decidable and Monoid tools.
--
--
-- writeStatement
-- (divided (encode "foo" encodeDefault)
-- (encode "bar" encodeDefault))
-- mempty
-- "INSERT INTO t (a, b) VALUES ($foo, $bar)"
-- :: (EncodeDefault x, EncodeDefault y)
-- => Statement Write (x, y) ()
--
--
-- Pro-tip: Consider using the IsString instance for Input.
-- For example, "foo" means encode "foo"
-- encodeDefault. That is, the last example could be written
-- as follows:
--
--
-- writeStatement
-- (divided "foo" "bar")
-- mempty
-- "INSERT INTO t (a, b) VALUES ($foo, $bar)"
-- :: (EncodeDefault x, EncodeDefault y)
-- => Statement Write (x, y) ()
--
encode :: Name -> Encode i -> Input i
-- | Add a prefix Name to parameters names in the given
-- Input, separated by __
--
-- This is useful for making reusable Inputs. For example,
-- consider the following.
--
--
-- data Point = Point { x :: Int, y :: Int }
--
-- pointInput :: Input Point
-- pointInput = contramap (\case Point x _ -> x) "x" <>
-- contramap (\case Point _ y -> y) "y"
--
--
-- After input:
--
--
-- writeStatement
-- (divided (input "p1" pointInput)
-- (input "p2" pointInput))
-- mempty
-- [sql|
-- INSERT INTO vectors (ax, ay, bx, by)
-- VALUES ($p1__x, $p1__y, $p2__x, $p2__y) |]
-- :: Statement Write (Point, Point) ()
--
input :: Name -> Input i -> Input i
-- | How to encode a single Haskell value of type a into a SQLite
-- value.
newtype Encode a
-- | Encode a value of type a as SQLData.
--
-- Ideally, the type a should be small enough that this function
-- always returns Right. However, that can sometimes be annoying,
-- so we allow this function to fail with ErrEncode if necessary,
-- in which case an ErrInput exception will be eventually thrown
-- while trying to bind the relevant Input to a Statement.
-- Why? Because for example, not all Strings can be safely encoded
-- as a SQLText seeing as some non-unicode characters will
-- silently be lost in the conversion. So, we could either not have an
-- Encoder for String at all, which would be annoying, or
-- we could have ErrEncode as we do here in order to safely deal
-- with those obscure corner cases.
Encode :: (a -> Either ErrEncode SQLData) -> Encode a
-- | A convenience function for refining an Encoder through a
-- function that may fail with a String error message. The
-- CallStack is preserved.
--
-- If you need a more sophisticated refinement, use the Encode
-- constructor.
encodeRefine :: HasCallStack => (a -> Either String b) -> Encode b -> Encode a
-- | Default way to encode a Haskell value of type a into a single
-- SQLite column value.
--
-- If there there exist also a DecodeDefault instance for
-- a, then it must roundtrip with the EncodeDefault
-- instance for a.
class EncodeDefault a
-- | Default way to encode a Haskell value of type a into a single
-- SQLite column value.
encodeDefault :: EncodeDefault a => Encode a
-- | a's ColumnType if Just, otherwise
-- NullColumn.
encodeMaybe :: Encode a -> Encode (Maybe a)
-- | a's ColumnType if Left, otherwise b's
-- ColumnType.
encodeEither :: Encode a -> Encode b -> Encode (Either a b)
-- | IntegerColumn if it fits in Int64, otherwise
-- TextColumn.
encodeSizedIntegral :: (Integral a, Bits a, HasCallStack) => Encode a
-- | Encodes as TextColumn.
encodeAeson :: (a -> Value) -> Encode a
-- | BlobColumn.
encodeBinary :: (a -> Put) -> Encode a
-- | TextColumn.
encodeShow :: Show a => Encode a
-- | How to decode an output row from a single Statement.
--
--
data Output o
-- | Decode the column with the given Name.
--
--
-- readStatement
-- mempty
-- (decode "foo" decodeDefault)
-- "SELECT foo FROM t"
-- :: (DecodeDefault x)
-- => Statement Read () x
--
--
-- Note that by design, this library doesn't support positional
-- Output parameters. You must always pick a Name. In the
-- raw SQL, you can use AS to rename your output columns as
-- necessary.
--
--
-- readStatement
-- mempty
-- (decode "abc" decodeDefault)
-- "SELECT foo AS abc FROM t"
-- :: (DecodeDefault x)
-- => Statement Read () x
--
--
-- Multiple Outputss can be composed with Monoid,
-- Functor, Applicative, Alternative, Monad,
-- MonadPlus, MonadFail and MonadThrow tools.
--
--
-- readStatement
-- mempty
-- (do foo <- decode "foo" decodeDefault
-- when (foo > 10) do
-- fail "Oh no!"
-- bar <- decode "bar" decodeDefault
-- pure (foo, bar))
-- "SELECT foo, bar FROM t"
-- :: (DecodeDefault y)
-- => Statement Read () (Int, y)
--
--
-- Pro-tip: Consider using the IsString instance for
-- Output, where for example "foo" means
-- decode "foo" decodeDefault:
--
--
-- readStatement
-- (liftA2 (,) "foo" "bar")
-- mempty
-- "SELECT foo, bar FROM t"
-- :: (DecodeDefault x, DecodeDefault y)
-- => Statement Read () (x, y)
--
decode :: Name -> Decode o -> Output o
-- | Add a prefix Name to column names in the given Output,
-- separated by __
--
-- This is useful for making reusable Outputs. For example,
-- consider the following.
--
--
-- data Point = Point { x :: Int, y :: Int }
--
-- pointOutput :: Output Point
-- pointOutput = Point <$> "x" <*> "y"
--
--
-- After using output:
--
--
-- readStatement
-- mempty
-- (liftA2 (output "p1" pointInput)
-- (output "p2" pointInput))
-- [sql|
-- SELECT ax AS p1__x, ay AS p1__y,
-- bx AS p2__x, by AS p2__y
-- FROM vectors|]
-- :: Statement Read () (Point, Point)
--
output :: Name -> Output o -> Output o
-- | How to decode a single SQLite column value into a Haskell value of
-- type a.
newtype Decode a
-- | Decode a SQLData value into a value of type a.
Decode :: (SQLData -> Either ErrDecode a) -> Decode a
-- | A convenience function for refining a Decoder through a
-- function that may fail with a String error message. The
-- CallStack is preserved.
--
-- If you need a more sophisticated refinement, use the Decode
-- constructor.
decodeRefine :: HasCallStack => (a -> Either String b) -> Decode a -> Decode b
-- | Default way to decode a SQLite value into a Haskell value of type
-- a.
--
-- If there there exist also a EncodeDefault instance for
-- a, then it must roundtrip with the DecodeDefault
-- instance for a.
class DecodeDefault a
-- | Default way to decode a SQLite value into a Haskell value of type
-- a.
decodeDefault :: DecodeDefault a => Decode a
-- | Attempt to decode a first, otherwise attempt decode a
-- NullColumn as Nothing.
decodeMaybe :: Decode a -> Decode (Maybe a)
-- |
-- decodeEither da db = fmap Left da <|> fmap Right db
--
decodeEither :: Decode a -> Decode b -> Decode (Either a b)
-- | IntegerColumn.
decodeSizedIntegral :: (Integral a, Bits a) => Decode a
-- | TextColumn.
decodeAeson :: (Value -> Parser a) -> Decode a
-- | BlobColumn.
decodeBinary :: Get a -> Decode a
-- | TextColumn.
decodeRead :: Read a => Decode a
-- | Part of a binding name suitable to use with encode,
-- decode, input and output.
--
-- Construct with name or IsString.
data Name
-- |
-- - First character must be ASCII letter.
-- - Last character, if any, must be ASCII letter or ASCII digit.
-- - Characters between the first and last, if any, must be ASCII
-- letters, ASCII digits, or underscore.
--
name :: Text -> Either String Name
-- | Transactional g r t a groups together multiple
-- interactions with a same Transaction t that finally
-- produce a value of type a. Think of Transactional as
-- if it was STM.
--
--
-- - g is an ephemeral tag for the whole inteaction group that
-- prevents Refs and streams from escaping its intended
-- scope (like ST does it). Just ignore it, it will always be
-- polymorphic.
-- - r says whether the Transactional could potentially
-- be retried from scratch in order to observe a new snapshot of the
-- database (like STM does it). Learn more about this in
-- Retry.
-- - t says whether the Transactional could potentially
-- perform Write or Read-only operations.
-- - a is the Haskell value finally produced by a successfu
-- execution of the Transactional.
--
--
-- To execute a Transactional you will normally use one of
-- read or commit (or rollback or embed, but
-- those are less common).
--
--
-- -- We are using commit to execute the Transactional. This means
-- -- that the Transactional will have read and Write capabilities, that
-- -- it can retry, and that ultimately, unless there are unhandled
-- -- exceptions, the changes will be commited to the database.
-- Sq.commit pool do
--
-- -- We can execute Write Statements:
-- userId1 <- Sq.one insertUser "haskell@example.com"
--
-- -- And Read Statements:
-- userId2 <- Sq.one getUserIdByEmail "haskell@example.com"
--
-- -- We have MonadFail too:
-- when (userId1 /= userId2) do
-- fail "Something unexpected happened!"
--
-- -- We also have Refs, which work just like TVars:
-- ref <- newRef (0 :: Int)
--
-- -- catch behaves like catchSTM, undoing changes to Refs
-- -- and to the database itself when the original action fails:
-- userId3 <- catch
-- -- Something will fail ...
-- (do modifyRef ref (+ 1)
-- _ <- Sq.one insertUser "sqlite@example.com"
-- throwM FakeException123)
-- -- ... but there is a catch!
-- (\FakeException123 -> do
-- -- The observable universe has been reset to what it
-- -- was before the catch:
-- Sq.zero getUserIdByEmail "sqlite@example.com"
-- modifyRef ref (+ 10))
--
-- -- Only the effects from the exception handling function were preserved:
-- Sq.zero getUserIdByEmail "sqlite@example.com"
-- 10 <- readRef ref
--
-- -- retry and its synonyms mzero and empty not only discard changes as
-- -- catch does, but they also cause the ongoing Transaction to be
-- -- discarded, and the entire Transactional to be executed again on a
-- -- brand new Transaction observing a new snapshot of the database. For
-- -- example, the following code will keep retrying the whole Transactional
-- -- until the user with the specified email exists.
-- userId4 <- Sq.maybe getUserIdByEmail "nix@example.com" >>= \case
-- Just x -> pure x
-- Nothing -> retry
--
-- -- Presumably, this example was waiting for a concurrent connection to
-- -- insert said user. If we got here, it is because that happened.
--
-- -- As usual, mzero and empty can be handled by means of <|> and mplus,
-- -- or its synonym orElse.
-- False <- mplus (writeRef ref 8 >> mzero >> pure True)
-- (pure False)
--
-- -- The recent writeRef to 8 on the retryied Transactional was discarded:
-- 10 <- readRef ref
--
-- pure ()
--
data Transactional (g :: k) (r :: Retry) (t :: Mode) a
-- | Execute a Read-only Transactional in a fresh
-- Transaction that will be automatically released when done.
read :: forall {k} m (p :: Mode) a. (MonadIO m, SubMode p 'Read) => Pool p -> (forall (g :: k). () => Transactional g 'Retry 'Read a) -> m a
-- | Execute a read-Write Transactional in a fresh
-- Transaction that will be automatically committed when done.
commit :: forall {k} m a. MonadIO m => Pool 'Write -> (forall (g :: k). () => Transactional g 'Retry 'Write a) -> m a
-- | Execute a read-Write Transactional in a fresh
-- Transaction that will be automatically rolled-back when done.
--
-- This is mostly useful for testing.
rollback :: forall {k} m a. MonadIO m => Pool 'Write -> (forall (g :: k). () => Transactional g 'Retry 'Write a) -> m a
-- | Embeds all the actions in a Transactional as part of an ongoing
-- Transaction.
--
--
embed :: forall {k} m (t :: Mode) a. MonadIO m => Transaction t -> (forall (g :: k). () => Transactional g 'NoRetry t a) -> m a
-- | Like TVar, but you can use it inside Transactional
-- through the MonadRef and MonadAtomicRef vocabulary.
data Ref (g :: k) a
-- | retry behaves like STM's retry. It causes the
-- current Transaction to be cancelled so that a new one can take
-- its place and the entire Transactional is executed again. This
-- allows the Transactional to observe a new snapshot of the
-- database.
--
--
-- - retry, empty and mzero all do fundamentally
-- the same thing, however retry leads to better type inferrence
-- because it forces the r type-parameter to be
-- Retry.
-- - NOTICE You only need to use mzero if you need access
-- to a newer database snapshot. If all you want to do is undo some
-- Ref transformation effects, or undo database changes, then use
-- catch which doesn't abandon the Transaction.
-- - WARNING If we keep retrying and the database never
-- changes, then we will be stuck in a loop forever. To mitigate this,
-- when executing the Transactional through read,
-- commit or rollback, you may want to use timeout
-- to abort at some point in the future.
--
retry :: forall {k} (g :: k) (t :: Mode) a. Transactional g 'Retry t a
-- | orElse ma mb behaves like STM's
-- orElse ma mb. If ma completes without
-- executing retry, then that constitutes the entirety of
-- orElse ma mb. Otherwise, if ma executed
-- retry, then all the effects from ma are discared and
-- mb is tried in its place.
--
--
-- - orElse, <|> and mplus all do the same
-- thing, but orElse has a more general type because it doesn't
-- force the r type-parameter to be Retry.
--
orElse :: forall {k} (g :: k) (r :: Retry) (t :: Mode) a. Transactional g r t a -> Transactional g r t a -> Transactional g r t a
-- | Executes a Statement expected to return exactly one row.
--
--
one :: forall {k} (t :: Mode) (s :: Mode) i o (g :: k) (r :: Retry). SubMode t s => Statement s i o -> i -> Transactional g r t o
-- | Executes a Statement expected to return zero or one
-- rows.
--
--
maybe :: forall {k} (t :: Mode) (s :: Mode) i o (g :: k) (r :: Retry). SubMode t s => Statement s i o -> i -> Transactional g r t (Maybe o)
-- | Executes a Statement expected to return exactly zero
-- rows.
--
--
zero :: forall {k} (t :: Mode) (s :: Mode) i o (g :: k) (r :: Retry). SubMode t s => Statement s i o -> i -> Transactional g r t ()
-- | Executes a Statement expected to return one or more
-- rows.
--
--
some :: forall {k} (t :: Mode) (s :: Mode) i o (g :: k) (r :: Retry). SubMode t s => Statement s i o -> i -> Transactional g r t (Int64, NonEmpty o)
-- | Executes a Statement expected to return zero or more
-- rows.
--
--
-- - Returns the length of the list, too.
--
list :: forall {k} (t :: Mode) (s :: Mode) i o (g :: k) (r :: Retry). SubMode t s => Statement s i o -> i -> Transactional g r t (Int64, [o])
-- | Purely fold all the output rows.
fold :: forall {k} (t :: Mode) (s :: Mode) o z i (g :: k) (r :: Retry). SubMode t s => Fold o z -> Statement s i o -> i -> Transactional g r t z
-- | Impurely fold the output rows.
--
--
foldM :: forall {k} (t :: Mode) (s :: Mode) (g :: k) (r :: Retry) o z i. SubMode t s => FoldM (Transactional g r t) o z -> Statement s i o -> i -> Transactional g r t z
-- | Stream the output rows from a Statement in a way that
-- allows interleaving IO actions.
--
--
-- - An exclusive lock will be held on the Transaction while the
-- Stream is producing rows.
-- - The Transaction lock is released automatically if the
-- Stream is consumed until exhaustion.
-- - If you won't consume the Stream until exhaustion, then be
-- sure to exit m by means of runResourceT or similar as
-- soon as possible in order to release the Transaction lock.
--
streamIO :: forall (m :: Type -> Type) (t :: Mode) (s :: Mode) i o. (MonadResource m, SubMode t s) => Acquire (Transaction t) -> Statement s i o -> i -> Stream (Of o) m ()
-- | Fold the output rows from a Statement in a way that
-- allows interleaving IO actions.
--
--
-- - This is simpler alternative to streamIO for when all you
-- need to do is fold.
-- - If you don't need to interleave IO actions, then consider
-- using fold.
--
foldIO :: forall m (t :: Mode) (s :: Mode) o z i. (MonadIO m, MonadMask m, SubMode t s) => FoldM m o z -> Acquire (Transaction t) -> Statement s i o -> i -> m z
-- | Pool of connections to a SQLite database.
--
--
-- - p indicates whether Read-only or read-Write
-- Statements are supported by this Pool.
-- - Obtain with readPool, writePool or
-- tempPool.
-- - It's safe and efficient to use a Pool concurrently as is.
-- Concurrency is handled internally.
--
data Pool (p :: Mode)
-- | Acquire a Read-only Pool according to the given
-- Settings.
--
--
readPool :: Df1 -> Settings -> Acquire (Pool 'Read)
-- | Acquire a read-Write Pool according to the given
-- Settings.
--
--
writePool :: Df1 -> Settings -> Acquire (Pool 'Write)
-- | Acquire a read-Write Pool temporarily persisted in the
-- file-system. It will be deleted once released. This can be useful for
-- testing.
--
--
tempPool :: Df1 -> Acquire (Pool 'Write)
-- | Use subPool to obtain the Read-only subset from a
-- read-Write Pool.
--
--
-- - Useful if you are passing the Pool as an argument to some
-- code, and you want to ensure that it can't performs Write
-- operations on it.
-- - The “new” Pool is not new. It shares all the underlying
-- resources with the original one, including their lifetime.
--
subPool :: Pool 'Write -> Pool 'Read
-- | SQLite connection settings.
data Settings
Settings :: FilePath -> SQLVFS -> Word32 -> Settings
-- | Database file path. Not an URI.
--
-- Note: To keep things simple, native :memory: SQLite databases
-- are not supported. Maybe use poolTemp or tmpfs if you
-- need that?
[file] :: Settings -> FilePath
[vfs] :: Settings -> SQLVFS
-- | SQLite busy Timeout in milliseconds.
[timeout] :: Settings -> Word32
-- | Default connection settings.
settings :: FilePath -> Settings
-- | A database transaction handle.
--
--
-- - t indicates whether Read-only or read-Write
-- Statements are supported.
-- - Prefer to use a Read-only Transaction if you are
-- solely performing Read-only Statements. It will be more
-- efficient in concurrent settings.
-- - Obtain with readTransaction or commitTransaction.
-- Or, if you are testing, with rollbackTransaction.
-- - If you have access to a Transaction within its intended
-- scope, then you can assume that a database transaction has started,
-- and will eventually be automatically commited or rolled back as
-- requested when it was obtained.
-- - It's safe and efficient to use a Transaction concurrently
-- as is. Concurrency is handled internally.
--
data Transaction (t :: Mode)
-- | Acquire a read-only transaction.
--
--
-- - You may need this function if you are using one of embed,
-- foldIO or streamIO. Otherwise, just use
-- read.
--
readTransaction :: forall (mode :: Mode). Pool mode -> Acquire (Transaction 'Read)
-- | Acquire a read-write transaction where changes are finally commited to
-- the database unless there is an unhandled exception during the
-- transaction, in which case they are rolled back.
--
--
commitTransaction :: Pool 'Write -> Acquire (Transaction 'Write)
-- | Acquire a read-write transaction where changes are always rolled back.
-- This is mostly useful for testing purposes.
--
--
rollbackTransaction :: Pool 'Write -> Acquire (Transaction 'Write)
-- | Acquire through MonadResource.
--
--
-- new = fmap snd . Data.Acquire.allocateAcquire
--
new :: MonadResource m => Acquire a -> m a
-- | Acquire through MonadMask.
--
--
-- with = Control.Monad.Trans.Resource.Extra.withAcquire.
--
with :: (MonadMask m, MonadIO m) => Acquire a -> (a -> m b) -> m b
-- | Acquire through MonadUnliftIO.
--
--
-- uith = Data.Acquire.with
--
uith :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b
-- | See savepoint, savepointRollback and
-- savepointRelease.
--
--
data Savepoint
-- | Obtain savepoint to which one can later savepointRollback or
-- savepointRelease.
savepoint :: MonadIO m => Transaction 'Write -> m Savepoint
-- | Disregard all the changes that happened to the Transaction
-- related to this Savepoint since the time it was obtained
-- through savepoint.
--
--
savepointRollback :: MonadIO m => Savepoint -> m ()
-- | Release a Savepoint so that it, together with any previous
-- Savepoints on the same Transaction, become unreachable
-- to future uses of savepointRollback or savepointRelease.
--
--
savepointRelease :: MonadIO m => Savepoint -> m ()
-- | Used as the r type-parameter in Transactional g r
-- t a.
--
--
data Retry
NoRetry :: Retry
Retry :: Retry
-- | A non-empty list of Names that can be rendered as Input
-- or Output parameters in a Statement.
--
-- As a user of Sq, you never construct a BindingName
-- manually. Rather, uses of input and output build one for
-- you from its Name constituents. BindingNames are only
-- exposed to you through ErrInput, ErrOutput and
-- ErrStatement.
data BindingName
data Mode
-- |
Read :: Mode
-- |
Write :: Mode
class SubMode (sup :: Mode) (sub :: Mode)
-- | The NULL SQL datatype.
--
-- Mostly useful if you want to encode or decode a literal NULL
-- value through EncodeDefault and DecodeDefault instances.
--
-- However, often you can benefit from encodeMaybe and
-- decodeMaybe instead.
data Null
Null :: Null
-- | See Encode.
newtype ErrEncode
ErrEncode :: SomeException -> ErrEncode
-- | See Encode.
data ErrInput
ErrInput :: BindingName -> ErrEncode -> ErrInput
-- | See Decode.
data ErrDecode
-- | Received ColumnType, expected ColumnTypes.
ErrDecode_Type :: ColumnType -> [ColumnType] -> ErrDecode
ErrDecode_Fail :: SomeException -> ErrDecode
data ErrOutput
-- | Error from Decode.
ErrOutput_ColumnValue :: BindingName -> ErrDecode -> ErrOutput
-- | Missing column name in the raw SQL.
ErrOutput_ColumnMissing :: BindingName -> ErrOutput
-- | Error from MonadThrow.
ErrOutput_Fail :: SomeException -> ErrOutput
data ErrStatement
-- | A same column name appears twice or more in the raw SQL.
ErrStatement_DuplicateColumnName :: BindingName -> ErrStatement
data ErrRows
-- | Fewer rows than requested were available.
ErrRows_TooFew :: ErrRows
-- | More rows than requested were available.
ErrRows_TooMany :: ErrRows
data SQLData
SQLInteger :: !Int64 -> SQLData
SQLFloat :: !Double -> SQLData
SQLText :: !Text -> SQLData
SQLBlob :: !ByteString -> SQLData
SQLNull :: SQLData
-- | These VFS names are used when using the open2 function.
data SQLVFS
SQLVFSDefault :: SQLVFS
SQLVFSUnix :: SQLVFS
SQLVFSUnixDotFile :: SQLVFS
SQLVFSUnixExcl :: SQLVFS
SQLVFSUnixNone :: SQLVFS
SQLVFSUnixNamedSem :: SQLVFS
SQLVFSCustom :: Text -> SQLVFS