module Database.HDBC.Record.Query (
PreparedQuery, prepare, prepareQuery, withPrepareQuery,
fetch, fetchAll, fetchAll',
listToUnique, fetchUnique, fetchUnique',
runStatement, runStatement',
runPreparedQuery, runPreparedQuery',
runQuery, runQuery'
) where
import Data.Maybe (listToMaybe)
import Database.HDBC (IConnection, Statement, SqlValue)
import qualified Database.HDBC as HDBC
import Database.Relational.Query (Query, untypeQuery)
import Database.Record
(ToSql, RecordFromSql, FromSql(recordFromSql), runToRecord)
import Database.HDBC.Record.Statement
(unsafePrepare, withUnsafePrepare, PreparedStatement,
bind, BoundStatement,
execute, ExecutedStatement, executed)
type PreparedQuery p a = PreparedStatement p a
prepare :: IConnection conn
=> conn
-> Query p a
-> IO (PreparedQuery p a)
prepare conn = unsafePrepare conn . untypeQuery
prepareQuery :: IConnection conn
=> conn
-> Query p a
-> IO (PreparedQuery p a)
prepareQuery = prepare
withPrepareQuery :: IConnection conn
=> conn
-> Query p a
-> (PreparedQuery p a -> IO b)
-> IO b
withPrepareQuery conn = withUnsafePrepare conn . untypeQuery
fetchRecordsExplicit :: Functor f
=> (Statement -> IO (f [SqlValue]) )
-> RecordFromSql SqlValue a
-> ExecutedStatement a
-> IO (f a)
fetchRecordsExplicit fetchs fromSql es = do
rows <- fetchs (executed es)
return $ fmap (runToRecord fromSql) rows
fetch :: FromSql SqlValue a => ExecutedStatement a -> IO (Maybe a)
fetch = fetchRecordsExplicit HDBC.fetchRow recordFromSql
fetchAll :: FromSql SqlValue a => ExecutedStatement a -> IO [a]
fetchAll = fetchRecordsExplicit HDBC.fetchAllRows recordFromSql
fetchAll' :: FromSql SqlValue a => ExecutedStatement a -> IO [a]
fetchAll' = fetchRecordsExplicit HDBC.fetchAllRows' recordFromSql
fetchUnique :: FromSql SqlValue a => ExecutedStatement a -> IO (Maybe a)
fetchUnique es = do
recs <- fetchAll es
let z' = listToMaybe recs
z <- z' `seq` return z'
HDBC.finish $ executed es
return z
listToUnique :: [a] -> IO (Maybe a)
listToUnique = d where
d [] = return Nothing
d [r] = return $ Just r
d (_:_:_) = fail "fetchUnique': more than one record found."
fetchUnique' :: FromSql SqlValue a => ExecutedStatement a -> IO (Maybe a)
fetchUnique' es = do
recs <- fetchAll es
z <- listToUnique recs
HDBC.finish $ executed es
return z
runStatement :: FromSql SqlValue a => BoundStatement a -> IO [a]
runStatement = (>>= fetchAll) . execute
runStatement' :: FromSql SqlValue a => BoundStatement a -> IO [a]
runStatement' = (>>= fetchAll') . execute
runPreparedQuery :: (ToSql SqlValue p, FromSql SqlValue a)
=> PreparedQuery p a
-> p
-> IO [a]
runPreparedQuery ps = runStatement . bind ps
runPreparedQuery' :: (ToSql SqlValue p, FromSql SqlValue a)
=> PreparedQuery p a
-> p
-> IO [a]
runPreparedQuery' ps = runStatement' . bind ps
runQuery :: (IConnection conn, ToSql SqlValue p, FromSql SqlValue a)
=> conn
-> Query p a
-> p
-> IO [a]
runQuery conn q p = prepare conn q >>= (`runPreparedQuery` p)
runQuery' :: (IConnection conn, ToSql SqlValue p, FromSql SqlValue a)
=> conn
-> Query p a
-> p
-> IO [a]
runQuery' conn q p = withPrepareQuery conn q (`runPreparedQuery'` p)