{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, GeneralizedNewtypeDeriving, ScopedTypeVariables, GADTs #-}
module Database.SQLite.Simple (
Query(..)
, Connection(..)
, ToRow(..)
, FromRow(..)
, Only(..)
, (:.)(..)
, Base.SQLData(..)
, Statement(..)
, ColumnIndex(..)
, NamedParam(..)
, open
, close
, withConnection
, setTrace
, query
, query_
, queryWith
, queryWith_
, queryNamed
, lastInsertRowId
, changes
, totalChanges
, fold
, fold_
, foldNamed
, execute
, execute_
, executeMany
, executeNamed
, field
, withTransaction
, withImmediateTransaction
, withExclusiveTransaction
, openStatement
, closeStatement
, withStatement
, bind
, bindNamed
, reset
, columnName
, columnCount
, withBind
, nextRow
, FormatError(..)
, ResultError(..)
, Base.SQLError(..)
, Base.Error(..)
) where
import Control.Exception
import Control.Monad (void, when, forM_)
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State.Strict
import Data.Int (Int64)
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import Data.Typeable (Typeable)
import Database.SQLite.Simple.Types
import qualified Database.SQLite3 as Base
import qualified Database.SQLite3.Direct as BaseD
import Database.SQLite.Simple.FromField (ResultError(..))
import Database.SQLite.Simple.FromRow
import Database.SQLite.Simple.Internal
import Database.SQLite.Simple.Ok
import Database.SQLite.Simple.ToField (ToField(..))
import Database.SQLite.Simple.ToRow (ToRow(..))
newtype Statement = Statement { Statement -> Statement
unStatement :: Base.Statement }
newtype ColumnIndex = ColumnIndex BaseD.ColumnIndex
deriving (ColumnIndex -> ColumnIndex -> Bool
(ColumnIndex -> ColumnIndex -> Bool)
-> (ColumnIndex -> ColumnIndex -> Bool) -> Eq ColumnIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColumnIndex -> ColumnIndex -> Bool
$c/= :: ColumnIndex -> ColumnIndex -> Bool
== :: ColumnIndex -> ColumnIndex -> Bool
$c== :: ColumnIndex -> ColumnIndex -> Bool
Eq, Eq ColumnIndex
Eq ColumnIndex =>
(ColumnIndex -> ColumnIndex -> Ordering)
-> (ColumnIndex -> ColumnIndex -> Bool)
-> (ColumnIndex -> ColumnIndex -> Bool)
-> (ColumnIndex -> ColumnIndex -> Bool)
-> (ColumnIndex -> ColumnIndex -> Bool)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> Ord ColumnIndex
ColumnIndex -> ColumnIndex -> Bool
ColumnIndex -> ColumnIndex -> Ordering
ColumnIndex -> ColumnIndex -> ColumnIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cmin :: ColumnIndex -> ColumnIndex -> ColumnIndex
max :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cmax :: ColumnIndex -> ColumnIndex -> ColumnIndex
>= :: ColumnIndex -> ColumnIndex -> Bool
$c>= :: ColumnIndex -> ColumnIndex -> Bool
> :: ColumnIndex -> ColumnIndex -> Bool
$c> :: ColumnIndex -> ColumnIndex -> Bool
<= :: ColumnIndex -> ColumnIndex -> Bool
$c<= :: ColumnIndex -> ColumnIndex -> Bool
< :: ColumnIndex -> ColumnIndex -> Bool
$c< :: ColumnIndex -> ColumnIndex -> Bool
compare :: ColumnIndex -> ColumnIndex -> Ordering
$ccompare :: ColumnIndex -> ColumnIndex -> Ordering
$cp1Ord :: Eq ColumnIndex
Ord, Int -> ColumnIndex
ColumnIndex -> Int
ColumnIndex -> [ColumnIndex]
ColumnIndex -> ColumnIndex
ColumnIndex -> ColumnIndex -> [ColumnIndex]
ColumnIndex -> ColumnIndex -> ColumnIndex -> [ColumnIndex]
(ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex)
-> (Int -> ColumnIndex)
-> (ColumnIndex -> Int)
-> (ColumnIndex -> [ColumnIndex])
-> (ColumnIndex -> ColumnIndex -> [ColumnIndex])
-> (ColumnIndex -> ColumnIndex -> [ColumnIndex])
-> (ColumnIndex -> ColumnIndex -> ColumnIndex -> [ColumnIndex])
-> Enum ColumnIndex
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ColumnIndex -> ColumnIndex -> ColumnIndex -> [ColumnIndex]
$cenumFromThenTo :: ColumnIndex -> ColumnIndex -> ColumnIndex -> [ColumnIndex]
enumFromTo :: ColumnIndex -> ColumnIndex -> [ColumnIndex]
$cenumFromTo :: ColumnIndex -> ColumnIndex -> [ColumnIndex]
enumFromThen :: ColumnIndex -> ColumnIndex -> [ColumnIndex]
$cenumFromThen :: ColumnIndex -> ColumnIndex -> [ColumnIndex]
enumFrom :: ColumnIndex -> [ColumnIndex]
$cenumFrom :: ColumnIndex -> [ColumnIndex]
fromEnum :: ColumnIndex -> Int
$cfromEnum :: ColumnIndex -> Int
toEnum :: Int -> ColumnIndex
$ctoEnum :: Int -> ColumnIndex
pred :: ColumnIndex -> ColumnIndex
$cpred :: ColumnIndex -> ColumnIndex
succ :: ColumnIndex -> ColumnIndex
$csucc :: ColumnIndex -> ColumnIndex
Enum, Integer -> ColumnIndex
ColumnIndex -> ColumnIndex
ColumnIndex -> ColumnIndex -> ColumnIndex
(ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex)
-> (Integer -> ColumnIndex)
-> Num ColumnIndex
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> ColumnIndex
$cfromInteger :: Integer -> ColumnIndex
signum :: ColumnIndex -> ColumnIndex
$csignum :: ColumnIndex -> ColumnIndex
abs :: ColumnIndex -> ColumnIndex
$cabs :: ColumnIndex -> ColumnIndex
negate :: ColumnIndex -> ColumnIndex
$cnegate :: ColumnIndex -> ColumnIndex
* :: ColumnIndex -> ColumnIndex -> ColumnIndex
$c* :: ColumnIndex -> ColumnIndex -> ColumnIndex
- :: ColumnIndex -> ColumnIndex -> ColumnIndex
$c- :: ColumnIndex -> ColumnIndex -> ColumnIndex
+ :: ColumnIndex -> ColumnIndex -> ColumnIndex
$c+ :: ColumnIndex -> ColumnIndex -> ColumnIndex
Num, Num ColumnIndex
Ord ColumnIndex
(Num ColumnIndex, Ord ColumnIndex) =>
(ColumnIndex -> Rational) -> Real ColumnIndex
ColumnIndex -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
toRational :: ColumnIndex -> Rational
$ctoRational :: ColumnIndex -> Rational
$cp2Real :: Ord ColumnIndex
$cp1Real :: Num ColumnIndex
Real, Enum ColumnIndex
Real ColumnIndex
(Real ColumnIndex, Enum ColumnIndex) =>
(ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> ColumnIndex)
-> (ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex))
-> (ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex))
-> (ColumnIndex -> Integer)
-> Integral ColumnIndex
ColumnIndex -> Integer
ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex)
ColumnIndex -> ColumnIndex -> ColumnIndex
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: ColumnIndex -> Integer
$ctoInteger :: ColumnIndex -> Integer
divMod :: ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex)
$cdivMod :: ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex)
quotRem :: ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex)
$cquotRem :: ColumnIndex -> ColumnIndex -> (ColumnIndex, ColumnIndex)
mod :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cmod :: ColumnIndex -> ColumnIndex -> ColumnIndex
div :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cdiv :: ColumnIndex -> ColumnIndex -> ColumnIndex
rem :: ColumnIndex -> ColumnIndex -> ColumnIndex
$crem :: ColumnIndex -> ColumnIndex -> ColumnIndex
quot :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cquot :: ColumnIndex -> ColumnIndex -> ColumnIndex
$cp2Integral :: Enum ColumnIndex
$cp1Integral :: Real ColumnIndex
Integral)
data NamedParam where
(:=) :: (ToField v) => T.Text -> v -> NamedParam
data TransactionType = Deferred | Immediate | Exclusive
infixr 3 :=
instance Show NamedParam where
show :: NamedParam -> String
show (k :: Text
k := v :: v
v) = (Text, SQLData) -> String
forall a. Show a => a -> String
show (Text
k, v -> SQLData
forall a. ToField a => a -> SQLData
toField v
v)
data FormatError = FormatError {
FormatError -> String
fmtMessage :: String
, FormatError -> Query
fmtQuery :: Query
, FormatError -> [String]
fmtParams :: [String]
} deriving (FormatError -> FormatError -> Bool
(FormatError -> FormatError -> Bool)
-> (FormatError -> FormatError -> Bool) -> Eq FormatError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FormatError -> FormatError -> Bool
$c/= :: FormatError -> FormatError -> Bool
== :: FormatError -> FormatError -> Bool
$c== :: FormatError -> FormatError -> Bool
Eq, Int -> FormatError -> ShowS
[FormatError] -> ShowS
FormatError -> String
(Int -> FormatError -> ShowS)
-> (FormatError -> String)
-> ([FormatError] -> ShowS)
-> Show FormatError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FormatError] -> ShowS
$cshowList :: [FormatError] -> ShowS
show :: FormatError -> String
$cshow :: FormatError -> String
showsPrec :: Int -> FormatError -> ShowS
$cshowsPrec :: Int -> FormatError -> ShowS
Show, Typeable)
instance Exception FormatError
open :: String -> IO Connection
open :: String -> IO Connection
open fname :: String
fname = Database -> Connection
Connection (Database -> Connection) -> IO Database -> IO Connection
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> IO Database
Base.open (String -> Text
T.pack String
fname)
close :: Connection -> IO ()
close :: Connection -> IO ()
close (Connection c :: Database
c) = Database -> IO ()
Base.close Database
c
withConnection :: String -> (Connection -> IO a) -> IO a
withConnection :: String -> (Connection -> IO a) -> IO a
withConnection connString :: String
connString = IO Connection
-> (Connection -> IO ()) -> (Connection -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (String -> IO Connection
open String
connString) Connection -> IO ()
close
unUtf8 :: BaseD.Utf8 -> T.Text
unUtf8 :: Utf8 -> Text
unUtf8 (BaseD.Utf8 bs :: ByteString
bs) = ByteString -> Text
TE.decodeUtf8 ByteString
bs
setTrace :: Connection -> Maybe (T.Text -> IO ()) -> IO ()
setTrace :: Connection -> Maybe (Text -> IO ()) -> IO ()
setTrace (Connection db :: Database
db) logger :: Maybe (Text -> IO ())
logger =
Database -> Maybe (Utf8 -> IO ()) -> IO ()
BaseD.setTrace Database
db (((Text -> IO ()) -> Utf8 -> IO ())
-> Maybe (Text -> IO ()) -> Maybe (Utf8 -> IO ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\lf :: Text -> IO ()
lf -> Text -> IO ()
lf (Text -> IO ()) -> (Utf8 -> Text) -> Utf8 -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Utf8 -> Text
unUtf8) Maybe (Text -> IO ())
logger)
bind :: (ToRow params) => Statement -> params -> IO ()
bind :: Statement -> params -> IO ()
bind (Statement stmt :: Statement
stmt) params :: params
params = do
let qp :: [SQLData]
qp = params -> [SQLData]
forall a. ToRow a => a -> [SQLData]
toRow params
params
ParamIndex
stmtParamCount <- Statement -> IO ParamIndex
Base.bindParameterCount Statement
stmt
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([SQLData] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SQLData]
qp Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= ParamIndex -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ParamIndex
stmtParamCount) ([SQLData] -> ParamIndex -> IO ()
throwColumnMismatch [SQLData]
qp ParamIndex
stmtParamCount)
(ParamIndex -> IO ()) -> [ParamIndex] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ([SQLData] -> ParamIndex -> IO ()
errorCheckParamName [SQLData]
qp) [1..ParamIndex
stmtParamCount]
Statement -> [SQLData] -> IO ()
Base.bind Statement
stmt [SQLData]
qp
where
throwColumnMismatch :: [SQLData] -> ParamIndex -> IO ()
throwColumnMismatch qp :: [SQLData]
qp nParams :: ParamIndex
nParams = do
Query
templ <- Statement -> IO Query
getQuery Statement
stmt
String -> Query -> [SQLData] -> IO ()
forall v a. Show v => String -> Query -> [v] -> a
fmtError ("SQL query contains " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ParamIndex -> String
forall a. Show a => a -> String
show ParamIndex
nParams String -> ShowS
forall a. [a] -> [a] -> [a]
++ " params, but " String -> ShowS
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show ([SQLData] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SQLData]
qp) String -> ShowS
forall a. [a] -> [a] -> [a]
++ " arguments given") Query
templ [SQLData]
qp
errorCheckParamName :: [SQLData] -> ParamIndex -> IO ()
errorCheckParamName qp :: [SQLData]
qp paramNdx :: ParamIndex
paramNdx = do
Query
templ <- Statement -> IO Query
getQuery Statement
stmt
Maybe Text
name <- Statement -> ParamIndex -> IO (Maybe Text)
Base.bindParameterName Statement
stmt ParamIndex
paramNdx
case Maybe Text
name of
Just n :: Text
n ->
String -> Query -> [SQLData] -> IO ()
forall v a. Show v => String -> Query -> [v] -> a
fmtError ("Only unnamed '?' query parameters are accepted, '"String -> ShowS
forall a. [a] -> [a] -> [a]
++Text -> String
T.unpack Text
nString -> ShowS
forall a. [a] -> [a] -> [a]
++"' given")
Query
templ [SQLData]
qp
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return (() -> IO ()) -> () -> IO ()
forall a b. (a -> b) -> a -> b
$! ()
bindNamed :: Statement -> [NamedParam] -> IO ()
bindNamed :: Statement -> [NamedParam] -> IO ()
bindNamed (Statement stmt :: Statement
stmt) params :: [NamedParam]
params = do
ParamIndex
stmtParamCount <- Statement -> IO ParamIndex
Base.bindParameterCount Statement
stmt
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([NamedParam] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NamedParam]
params Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= ParamIndex -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ParamIndex
stmtParamCount) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ ParamIndex -> IO ()
throwColumnMismatch ParamIndex
stmtParamCount
Statement -> [NamedParam] -> IO ()
bind Statement
stmt [NamedParam]
params
where
bind :: Statement -> [NamedParam] -> IO ()
bind stmt :: Statement
stmt params :: [NamedParam]
params =
(NamedParam -> IO ()) -> [NamedParam] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(n :: Text
n := v :: v
v) -> do
Maybe ParamIndex
idx <- Statement -> Utf8 -> IO (Maybe ParamIndex)
BaseD.bindParameterIndex Statement
stmt (ByteString -> Utf8
BaseD.Utf8 (ByteString -> Utf8) -> (Text -> ByteString) -> Text -> Utf8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
TE.encodeUtf8 (Text -> Utf8) -> Text -> Utf8
forall a b. (a -> b) -> a -> b
$ Text
n)
case Maybe ParamIndex
idx of
Just i :: ParamIndex
i ->
Statement -> ParamIndex -> SQLData -> IO ()
Base.bindSQLData Statement
stmt ParamIndex
i (v -> SQLData
forall a. ToField a => a -> SQLData
toField v
v)
Nothing -> do
Query
templ <- Statement -> IO Query
getQuery Statement
stmt
String -> Query -> [NamedParam] -> IO ()
forall v a. Show v => String -> Query -> [v] -> a
fmtError ("Unknown named parameter '" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
n String -> ShowS
forall a. [a] -> [a] -> [a]
++ "'")
Query
templ [NamedParam]
params)
[NamedParam]
params
throwColumnMismatch :: ParamIndex -> IO ()
throwColumnMismatch nParams :: ParamIndex
nParams = do
Query
templ <- Statement -> IO Query
getQuery Statement
stmt
String -> Query -> [NamedParam] -> IO ()
forall v a. Show v => String -> Query -> [v] -> a
fmtError ("SQL query contains " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ParamIndex -> String
forall a. Show a => a -> String
show ParamIndex
nParams String -> ShowS
forall a. [a] -> [a] -> [a]
++ " params, but " String -> ShowS
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show ([NamedParam] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NamedParam]
params) String -> ShowS
forall a. [a] -> [a] -> [a]
++ " arguments given") Query
templ [NamedParam]
params
reset :: Statement -> IO ()
reset :: Statement -> IO ()
reset (Statement stmt :: Statement
stmt) = Statement -> IO ()
Base.reset Statement
stmt
columnName :: Statement -> ColumnIndex -> IO T.Text
columnName :: Statement -> ColumnIndex -> IO Text
columnName (Statement stmt :: Statement
stmt) (ColumnIndex n :: ColumnIndex
n) = Statement -> ColumnIndex -> IO (Maybe Utf8)
BaseD.columnName Statement
stmt ColumnIndex
n IO (Maybe Utf8) -> (Maybe Utf8 -> IO Text) -> IO Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Utf8 -> IO Text
takeUtf8
where
takeUtf8 :: Maybe Utf8 -> IO Text
takeUtf8 (Just s :: Utf8
s) = Text -> IO Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> IO Text) -> Text -> IO Text
forall a b. (a -> b) -> a -> b
$ Utf8 -> Text
unUtf8 Utf8
s
takeUtf8 Nothing =
ArrayException -> IO Text
forall e a. Exception e => e -> IO a
throwIO (String -> ArrayException
IndexOutOfBounds ("Column index " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ColumnIndex -> String
forall a. Show a => a -> String
show ColumnIndex
n String -> ShowS
forall a. [a] -> [a] -> [a]
++ " out of bounds"))
columnCount :: Statement -> IO ColumnIndex
columnCount :: Statement -> IO ColumnIndex
columnCount (Statement stmt :: Statement
stmt) = ColumnIndex -> ColumnIndex
ColumnIndex (ColumnIndex -> ColumnIndex) -> IO ColumnIndex -> IO ColumnIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Statement -> IO ColumnIndex
BaseD.columnCount Statement
stmt
withBind :: (ToRow params) => Statement -> params -> IO a -> IO a
withBind :: Statement -> params -> IO a -> IO a
withBind stmt :: Statement
stmt params :: params
params io :: IO a
io = do
Statement -> params -> IO ()
forall params. ToRow params => Statement -> params -> IO ()
bind Statement
stmt params
params
IO a
io IO a -> IO () -> IO a
forall a b. IO a -> IO b -> IO a
`finally` Statement -> IO ()
reset Statement
stmt
openStatement :: Connection -> Query -> IO Statement
openStatement :: Connection -> Query -> IO Statement
openStatement (Connection c :: Database
c) (Query t :: Text
t) = do
Statement
stmt <- Database -> Text -> IO Statement
Base.prepare Database
c Text
t
Statement -> IO Statement
forall (m :: * -> *) a. Monad m => a -> m a
return (Statement -> IO Statement) -> Statement -> IO Statement
forall a b. (a -> b) -> a -> b
$ Statement -> Statement
Statement Statement
stmt
closeStatement :: Statement -> IO ()
closeStatement :: Statement -> IO ()
closeStatement (Statement stmt :: Statement
stmt) = Statement -> IO ()
Base.finalize Statement
stmt
withStatement :: Connection -> Query -> (Statement -> IO a) -> IO a
withStatement :: Connection -> Query -> (Statement -> IO a) -> IO a
withStatement conn :: Connection
conn query :: Query
query = IO Statement -> (Statement -> IO ()) -> (Statement -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Connection -> Query -> IO Statement
openStatement Connection
conn Query
query) Statement -> IO ()
closeStatement
withStatementParams :: (ToRow params)
=> Connection
-> Query
-> params
-> (Statement -> IO a)
-> IO a
withStatementParams :: Connection -> Query -> params -> (Statement -> IO a) -> IO a
withStatementParams conn :: Connection
conn template :: Query
template params :: params
params action :: Statement -> IO a
action =
Connection -> Query -> (Statement -> IO a) -> IO a
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
template ((Statement -> IO a) -> IO a) -> (Statement -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt ->
Statement -> [SQLData] -> IO ()
forall params. ToRow params => Statement -> params -> IO ()
bind Statement
stmt (params -> [SQLData]
forall a. ToRow a => a -> [SQLData]
toRow params
params) IO () -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Statement -> IO a
action Statement
stmt
withStatementNamedParams :: Connection
-> Query
-> [NamedParam]
-> (Statement -> IO a)
-> IO a
withStatementNamedParams :: Connection -> Query -> [NamedParam] -> (Statement -> IO a) -> IO a
withStatementNamedParams conn :: Connection
conn template :: Query
template namedParams :: [NamedParam]
namedParams action :: Statement -> IO a
action =
Connection -> Query -> (Statement -> IO a) -> IO a
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
template ((Statement -> IO a) -> IO a) -> (Statement -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt -> Statement -> [NamedParam] -> IO ()
bindNamed Statement
stmt [NamedParam]
namedParams IO () -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Statement -> IO a
action Statement
stmt
execute :: (ToRow q) => Connection -> Query -> q -> IO ()
execute :: Connection -> Query -> q -> IO ()
execute conn :: Connection
conn template :: Query
template qs :: q
qs =
Connection -> Query -> q -> (Statement -> IO ()) -> IO ()
forall params a.
ToRow params =>
Connection -> Query -> params -> (Statement -> IO a) -> IO a
withStatementParams Connection
conn Query
template q
qs ((Statement -> IO ()) -> IO ()) -> (Statement -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Statement stmt :: Statement
stmt) ->
IO StepResult -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO StepResult -> IO ())
-> (Statement -> IO StepResult) -> Statement -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Statement -> IO StepResult
Base.step (Statement -> IO ()) -> Statement -> IO ()
forall a b. (a -> b) -> a -> b
$ Statement
stmt
executeMany :: ToRow q => Connection -> Query -> [q] -> IO ()
executeMany :: Connection -> Query -> [q] -> IO ()
executeMany conn :: Connection
conn template :: Query
template paramRows :: [q]
paramRows = Connection -> Query -> (Statement -> IO ()) -> IO ()
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
template ((Statement -> IO ()) -> IO ()) -> (Statement -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt -> do
let Statement stmt' :: Statement
stmt' = Statement
stmt
[q] -> (q -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [q]
paramRows ((q -> IO ()) -> IO ()) -> (q -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \params :: q
params ->
Statement -> q -> IO () -> IO ()
forall params a.
ToRow params =>
Statement -> params -> IO a -> IO a
withBind Statement
stmt q
params
(IO StepResult -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO StepResult -> IO ())
-> (Statement -> IO StepResult) -> Statement -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Statement -> IO StepResult
Base.step (Statement -> IO ()) -> Statement -> IO ()
forall a b. (a -> b) -> a -> b
$ Statement
stmt')
doFoldToList :: RowParser row -> Statement -> IO [row]
doFoldToList :: RowParser row -> Statement -> IO [row]
doFoldToList fromRow_ :: RowParser row
fromRow_ stmt :: Statement
stmt =
([row] -> [row]) -> IO [row] -> IO [row]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [row] -> [row]
forall a. [a] -> [a]
reverse (IO [row] -> IO [row]) -> IO [row] -> IO [row]
forall a b. (a -> b) -> a -> b
$ RowParser row
-> Statement -> [row] -> ([row] -> row -> IO [row]) -> IO [row]
forall row a.
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold RowParser row
fromRow_ Statement
stmt [] (\acc :: [row]
acc e :: row
e -> [row] -> IO [row]
forall (m :: * -> *) a. Monad m => a -> m a
return (row
e row -> [row] -> [row]
forall a. a -> [a] -> [a]
: [row]
acc))
query :: (ToRow q, FromRow r)
=> Connection -> Query -> q -> IO [r]
query :: Connection -> Query -> q -> IO [r]
query = RowParser r -> Connection -> Query -> q -> IO [r]
forall q r.
ToRow q =>
RowParser r -> Connection -> Query -> q -> IO [r]
queryWith RowParser r
forall a. FromRow a => RowParser a
fromRow
query_ :: (FromRow r) => Connection -> Query -> IO [r]
query_ :: Connection -> Query -> IO [r]
query_ = RowParser r -> Connection -> Query -> IO [r]
forall r. RowParser r -> Connection -> Query -> IO [r]
queryWith_ RowParser r
forall a. FromRow a => RowParser a
fromRow
queryWith :: (ToRow q) => RowParser r -> Connection -> Query -> q -> IO [r]
queryWith :: RowParser r -> Connection -> Query -> q -> IO [r]
queryWith fromRow_ :: RowParser r
fromRow_ conn :: Connection
conn templ :: Query
templ qs :: q
qs =
Connection -> Query -> q -> (Statement -> IO [r]) -> IO [r]
forall params a.
ToRow params =>
Connection -> Query -> params -> (Statement -> IO a) -> IO a
withStatementParams Connection
conn Query
templ q
qs ((Statement -> IO [r]) -> IO [r])
-> (Statement -> IO [r]) -> IO [r]
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt -> RowParser r -> Statement -> IO [r]
forall row. RowParser row -> Statement -> IO [row]
doFoldToList RowParser r
fromRow_ Statement
stmt
queryWith_ :: RowParser r -> Connection -> Query -> IO [r]
queryWith_ :: RowParser r -> Connection -> Query -> IO [r]
queryWith_ fromRow_ :: RowParser r
fromRow_ conn :: Connection
conn query :: Query
query =
Connection -> Query -> (Statement -> IO [r]) -> IO [r]
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
query (RowParser r -> Statement -> IO [r]
forall row. RowParser row -> Statement -> IO [row]
doFoldToList RowParser r
fromRow_)
queryNamed :: (FromRow r) => Connection -> Query -> [NamedParam] -> IO [r]
queryNamed :: Connection -> Query -> [NamedParam] -> IO [r]
queryNamed conn :: Connection
conn templ :: Query
templ params :: [NamedParam]
params =
Connection
-> Query -> [NamedParam] -> (Statement -> IO [r]) -> IO [r]
forall a.
Connection -> Query -> [NamedParam] -> (Statement -> IO a) -> IO a
withStatementNamedParams Connection
conn Query
templ [NamedParam]
params ((Statement -> IO [r]) -> IO [r])
-> (Statement -> IO [r]) -> IO [r]
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt -> RowParser r -> Statement -> IO [r]
forall row. RowParser row -> Statement -> IO [row]
doFoldToList RowParser r
forall a. FromRow a => RowParser a
fromRow Statement
stmt
execute_ :: Connection -> Query -> IO ()
execute_ :: Connection -> Query -> IO ()
execute_ conn :: Connection
conn template :: Query
template =
Connection -> Query -> (Statement -> IO ()) -> IO ()
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
template ((Statement -> IO ()) -> IO ()) -> (Statement -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Statement stmt :: Statement
stmt) ->
IO StepResult -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO StepResult -> IO ()) -> IO StepResult -> IO ()
forall a b. (a -> b) -> a -> b
$ Statement -> IO StepResult
Base.step Statement
stmt
executeNamed :: Connection -> Query -> [NamedParam] -> IO ()
executeNamed :: Connection -> Query -> [NamedParam] -> IO ()
executeNamed conn :: Connection
conn template :: Query
template params :: [NamedParam]
params =
Connection
-> Query -> [NamedParam] -> (Statement -> IO ()) -> IO ()
forall a.
Connection -> Query -> [NamedParam] -> (Statement -> IO a) -> IO a
withStatementNamedParams Connection
conn Query
template [NamedParam]
params ((Statement -> IO ()) -> IO ()) -> (Statement -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Statement stmt :: Statement
stmt) ->
IO StepResult -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO StepResult -> IO ()) -> IO StepResult -> IO ()
forall a b. (a -> b) -> a -> b
$ Statement -> IO StepResult
Base.step Statement
stmt
fold :: ( FromRow row, ToRow params )
=> Connection
-> Query
-> params
-> a
-> (a -> row -> IO a)
-> IO a
fold :: Connection -> Query -> params -> a -> (a -> row -> IO a) -> IO a
fold conn :: Connection
conn query :: Query
query params :: params
params initalState :: a
initalState action :: a -> row -> IO a
action =
Connection -> Query -> params -> (Statement -> IO a) -> IO a
forall params a.
ToRow params =>
Connection -> Query -> params -> (Statement -> IO a) -> IO a
withStatementParams Connection
conn Query
query params
params ((Statement -> IO a) -> IO a) -> (Statement -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt ->
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
forall row a.
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold RowParser row
forall a. FromRow a => RowParser a
fromRow Statement
stmt a
initalState a -> row -> IO a
action
fold_ :: ( FromRow row )
=> Connection
-> Query
-> a
-> (a -> row -> IO a)
-> IO a
fold_ :: Connection -> Query -> a -> (a -> row -> IO a) -> IO a
fold_ conn :: Connection
conn query :: Query
query initalState :: a
initalState action :: a -> row -> IO a
action =
Connection -> Query -> (Statement -> IO a) -> IO a
forall a. Connection -> Query -> (Statement -> IO a) -> IO a
withStatement Connection
conn Query
query ((Statement -> IO a) -> IO a) -> (Statement -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt ->
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
forall row a.
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold RowParser row
forall a. FromRow a => RowParser a
fromRow Statement
stmt a
initalState a -> row -> IO a
action
foldNamed :: ( FromRow row )
=> Connection
-> Query
-> [NamedParam]
-> a
-> (a -> row -> IO a)
-> IO a
foldNamed :: Connection
-> Query -> [NamedParam] -> a -> (a -> row -> IO a) -> IO a
foldNamed conn :: Connection
conn query :: Query
query params :: [NamedParam]
params initalState :: a
initalState action :: a -> row -> IO a
action =
Connection -> Query -> [NamedParam] -> (Statement -> IO a) -> IO a
forall a.
Connection -> Query -> [NamedParam] -> (Statement -> IO a) -> IO a
withStatementNamedParams Connection
conn Query
query [NamedParam]
params ((Statement -> IO a) -> IO a) -> (Statement -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \stmt :: Statement
stmt ->
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
forall row a.
RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold RowParser row
forall a. FromRow a => RowParser a
fromRow Statement
stmt a
initalState a -> row -> IO a
action
doFold :: RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold :: RowParser row -> Statement -> a -> (a -> row -> IO a) -> IO a
doFold fromRow_ :: RowParser row
fromRow_ stmt :: Statement
stmt initState :: a
initState action :: a -> row -> IO a
action =
a -> IO a
loop a
initState
where
loop :: a -> IO a
loop val :: a
val = do
Maybe row
maybeNextRow <- RowParser row -> Statement -> IO (Maybe row)
forall r. RowParser r -> Statement -> IO (Maybe r)
nextRowWith RowParser row
fromRow_ Statement
stmt
case Maybe row
maybeNextRow of
Just row :: row
row -> do
a
val' <- a -> row -> IO a
action a
val row
row
a
val' a -> IO a -> IO a
forall a b. a -> b -> b
`seq` a -> IO a
loop a
val'
Nothing -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
val
nextRow :: (FromRow r) => Statement -> IO (Maybe r)
nextRow :: Statement -> IO (Maybe r)
nextRow = RowParser r -> Statement -> IO (Maybe r)
forall r. RowParser r -> Statement -> IO (Maybe r)
nextRowWith RowParser r
forall a. FromRow a => RowParser a
fromRow
nextRowWith :: RowParser r -> Statement -> IO (Maybe r)
nextRowWith :: RowParser r -> Statement -> IO (Maybe r)
nextRowWith fromRow_ :: RowParser r
fromRow_ (Statement stmt :: Statement
stmt) = do
StepResult
statRes <- Statement -> IO StepResult
Base.step Statement
stmt
case StepResult
statRes of
Base.Row -> do
[SQLData]
rowRes <- Statement -> IO [SQLData]
Base.columns Statement
stmt
let nCols :: Int
nCols = [SQLData] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SQLData]
rowRes
r
row <- RowParser r -> [SQLData] -> Int -> IO r
forall r. RowParser r -> [SQLData] -> Int -> IO r
convertRow RowParser r
fromRow_ [SQLData]
rowRes Int
nCols
Maybe r -> IO (Maybe r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe r -> IO (Maybe r)) -> Maybe r -> IO (Maybe r)
forall a b. (a -> b) -> a -> b
$ r -> Maybe r
forall a. a -> Maybe a
Just r
row
Base.Done -> Maybe r -> IO (Maybe r)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe r
forall a. Maybe a
Nothing
convertRow :: RowParser r -> [Base.SQLData] -> Int -> IO r
convertRow :: RowParser r -> [SQLData] -> Int -> IO r
convertRow fromRow_ :: RowParser r
fromRow_ rowRes :: [SQLData]
rowRes ncols :: Int
ncols = do
let rw :: RowParseRO
rw = Int -> RowParseRO
RowParseRO Int
ncols
case StateT (Int, [SQLData]) Ok r
-> (Int, [SQLData]) -> Ok (r, (Int, [SQLData]))
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (ReaderT RowParseRO (StateT (Int, [SQLData]) Ok) r
-> RowParseRO -> StateT (Int, [SQLData]) Ok r
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (RowParser r -> ReaderT RowParseRO (StateT (Int, [SQLData]) Ok) r
forall a.
RowParser a -> ReaderT RowParseRO (StateT (Int, [SQLData]) Ok) a
unRP RowParser r
fromRow_) RowParseRO
rw) (0, [SQLData]
rowRes) of
Ok (val :: r
val,(col :: Int
col,_))
| Int
col Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ncols -> r -> IO r
forall (m :: * -> *) a. Monad m => a -> m a
return r
val
| Bool
otherwise -> ColumnOutOfBounds -> IO r
forall r. ColumnOutOfBounds -> IO r
errorColumnMismatch (Int -> ColumnOutOfBounds
ColumnOutOfBounds Int
col)
Errors [] -> ResultError -> IO r
forall e a. Exception e => e -> IO a
throwIO (ResultError -> IO r) -> ResultError -> IO r
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> ResultError
ConversionFailed "" "" "unknown error"
Errors [x :: SomeException
x] ->
SomeException -> IO r
forall a e. Exception e => e -> a
throw SomeException
x IO r -> (ColumnOutOfBounds -> IO r) -> IO r
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`Control.Exception.catch` (\e :: ColumnOutOfBounds
e -> ColumnOutOfBounds -> IO r
forall r. ColumnOutOfBounds -> IO r
errorColumnMismatch (ColumnOutOfBounds
e :: ColumnOutOfBounds))
Errors xs :: [SomeException]
xs -> ManyErrors -> IO r
forall e a. Exception e => e -> IO a
throwIO (ManyErrors -> IO r) -> ManyErrors -> IO r
forall a b. (a -> b) -> a -> b
$ [SomeException] -> ManyErrors
ManyErrors [SomeException]
xs
where
errorColumnMismatch :: ColumnOutOfBounds -> IO r
errorColumnMismatch :: ColumnOutOfBounds -> IO r
errorColumnMismatch (ColumnOutOfBounds c :: Int
c) = do
let vals :: [(ByteString, Text)]
vals = (SQLData -> (ByteString, Text))
-> [SQLData] -> [(ByteString, Text)]
forall a b. (a -> b) -> [a] -> [b]
map (\f :: SQLData
f -> (SQLData -> ByteString
gettypename SQLData
f, SQLData -> Text
ellipsis SQLData
f)) [SQLData]
rowRes
ResultError -> IO r
forall e a. Exception e => e -> IO a
throwIO (String -> String -> String -> ResultError
ConversionFailed
(Int -> String
forall a. Show a => a -> String
show Int
ncols String -> ShowS
forall a. [a] -> [a] -> [a]
++ " values: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(ByteString, Text)] -> String
forall a. Show a => a -> String
show [(ByteString, Text)]
vals)
("at least " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
c String -> ShowS
forall a. [a] -> [a] -> [a]
++ " slots in target type")
"mismatch between number of columns to convert and number in target type")
ellipsis :: Base.SQLData -> T.Text
ellipsis :: SQLData -> Text
ellipsis sql :: SQLData
sql
| Text -> Int
T.length Text
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 20 = Int -> Text -> Text
T.take 15 Text
bs Text -> Text -> Text
`T.append` "[...]"
| Bool
otherwise = Text
bs
where
bs :: Text
bs = String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ SQLData -> String
forall a. Show a => a -> String
show SQLData
sql
withTransactionPrivate :: Connection -> IO a -> TransactionType -> IO a
withTransactionPrivate :: Connection -> IO a -> TransactionType -> IO a
withTransactionPrivate conn :: Connection
conn action :: IO a
action ttype :: TransactionType
ttype =
((forall a. IO a -> IO a) -> IO a) -> IO a
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask (((forall a. IO a -> IO a) -> IO a) -> IO a)
-> ((forall a. IO a -> IO a) -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \restore :: forall a. IO a -> IO a
restore -> do
IO ()
begin
a
r <- IO a -> IO a
forall a. IO a -> IO a
restore IO a
action IO a -> IO () -> IO a
forall a b. IO a -> IO b -> IO a
`onException` IO ()
rollback
IO ()
commit
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
where
begin :: IO ()
begin = case TransactionType
ttype of
Deferred -> Connection -> Query -> IO ()
execute_ Connection
conn "BEGIN TRANSACTION"
Immediate -> Connection -> Query -> IO ()
execute_ Connection
conn "BEGIN IMMEDIATE TRANSACTION"
Exclusive -> Connection -> Query -> IO ()
execute_ Connection
conn "BEGIN EXCLUSIVE TRANSACTION"
commit :: IO ()
commit = Connection -> Query -> IO ()
execute_ Connection
conn "COMMIT TRANSACTION"
rollback :: IO ()
rollback = Connection -> Query -> IO ()
execute_ Connection
conn "ROLLBACK TRANSACTION"
withImmediateTransaction :: Connection -> IO a -> IO a
withImmediateTransaction :: Connection -> IO a -> IO a
withImmediateTransaction conn :: Connection
conn action :: IO a
action =
Connection -> IO a -> TransactionType -> IO a
forall a. Connection -> IO a -> TransactionType -> IO a
withTransactionPrivate Connection
conn IO a
action TransactionType
Immediate
withExclusiveTransaction :: Connection -> IO a -> IO a
withExclusiveTransaction :: Connection -> IO a -> IO a
withExclusiveTransaction conn :: Connection
conn action :: IO a
action =
Connection -> IO a -> TransactionType -> IO a
forall a. Connection -> IO a -> TransactionType -> IO a
withTransactionPrivate Connection
conn IO a
action TransactionType
Exclusive
lastInsertRowId :: Connection -> IO Int64
lastInsertRowId :: Connection -> IO Int64
lastInsertRowId (Connection c :: Database
c) = Database -> IO Int64
BaseD.lastInsertRowId Database
c
changes :: Connection -> IO Int
changes :: Connection -> IO Int
changes (Connection c :: Database
c) = Database -> IO Int
BaseD.changes Database
c
totalChanges :: Connection -> IO Int
totalChanges :: Connection -> IO Int
totalChanges (Connection c :: Database
c) = Database -> IO Int
BaseD.totalChanges Database
c
withTransaction :: Connection -> IO a -> IO a
withTransaction :: Connection -> IO a -> IO a
withTransaction conn :: Connection
conn action :: IO a
action =
Connection -> IO a -> TransactionType -> IO a
forall a. Connection -> IO a -> TransactionType -> IO a
withTransactionPrivate Connection
conn IO a
action TransactionType
Deferred
fmtError :: Show v => String -> Query -> [v] -> a
fmtError :: String -> Query -> [v] -> a
fmtError msg :: String
msg q :: Query
q xs :: [v]
xs =
FormatError -> a
forall a e. Exception e => e -> a
throw FormatError :: String -> Query -> [String] -> FormatError
FormatError {
fmtMessage :: String
fmtMessage = String
msg
, fmtQuery :: Query
fmtQuery = Query
q
, fmtParams :: [String]
fmtParams = (v -> String) -> [v] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map v -> String
forall a. Show a => a -> String
show [v]
xs
}
getQuery :: Base.Statement -> IO Query
getQuery :: Statement -> IO Query
getQuery stmt :: Statement
stmt =
Maybe Utf8 -> Query
toQuery (Maybe Utf8 -> Query) -> IO (Maybe Utf8) -> IO Query
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Statement -> IO (Maybe Utf8)
BaseD.statementSql Statement
stmt
where
toQuery :: Maybe Utf8 -> Query
toQuery =
Text -> Query
Query (Text -> Query) -> (Maybe Utf8 -> Text) -> Maybe Utf8 -> Query
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> (Utf8 -> Text) -> Maybe Utf8 -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "no query string" (\(BaseD.Utf8 s :: ByteString
s) -> ByteString -> Text
TE.decodeUtf8 ByteString
s)