Portability | portable |
---|---|
Stability | experimental |
Maintainer | Aleksey Uymanov <s9gf4ult@gmail.com> |
Safe Haskell | None |
Types for HDBI.
Written by John Goerzen, jgoerzen@complete.org
- class (Typeable conn, Statement (ConnStatement conn)) => Connection conn where
- type ConnStatement conn :: *
- disconnect :: conn -> IO ()
- begin :: conn -> IO ()
- commit :: conn -> IO ()
- rollback :: conn -> IO ()
- inTransaction :: conn -> IO Bool
- connStatus :: conn -> IO ConnStatus
- prepare :: conn -> Query -> IO (ConnStatement conn)
- run :: ToRow row => conn -> Query -> row -> IO ()
- runMany :: ToRow row => conn -> Query -> [row] -> IO ()
- runRaw :: conn -> Query -> IO ()
- clone :: conn -> IO conn
- hdbiDriverName :: conn -> String
- dbTransactionSupport :: conn -> Bool
- class Typeable stmt => Statement stmt where
- execute :: ToRow row => stmt -> row -> IO ()
- executeMany :: ToRow row => stmt -> [row] -> IO ()
- statementStatus :: stmt -> IO StatementStatus
- finish :: stmt -> IO ()
- reset :: stmt -> IO ()
- fetch :: FromRow row => stmt -> IO (Maybe row)
- fetchAll :: FromRow row => stmt -> IO (Seq row)
- getColumnNames :: stmt -> IO [Text]
- getColumnsCount :: stmt -> IO Int
- originalQuery :: stmt -> Query
- newtype Query = Query {
- unQuery :: Text
- data ConnStatus
- = ConnOK
- | ConnDisconnected
- | ConnBad
- data ConnWrapper = forall conn . Connection conn => ConnWrapper conn
- data StatementStatus
- data StmtWrapper = forall stmt . Statement stmt => StmtWrapper stmt
- data SqlError
- = SqlError { }
- | SqlDriverError {
- seErrorMsg :: String
- castConnection :: Connection conn => ConnWrapper -> Maybe conn
- castStatement :: Statement stmt => StmtWrapper -> Maybe stmt
- withTransaction :: Connection conn => conn -> IO a -> IO a
- withStatement :: (Connection conn, Statement stmt, stmt ~ ConnStatement conn) => conn -> Query -> (stmt -> IO a) -> IO a
- runFetch :: (Connection con, ToRow params, FromRow row) => con -> Query -> params -> IO (Maybe row)
- runFetchAll :: (Connection con, ToRow params, FromRow row) => con -> Query -> params -> IO (Seq row)
- runFetchOne :: (Connection con, ToRow params, FromSql col) => con -> Query -> params -> IO (Maybe col)
Typeclasses
class (Typeable conn, Statement (ConnStatement conn)) => Connection conn whereSource
Typeclass to abstract the working with connection.
type ConnStatement conn :: *Source
Specific statement for specific connection
disconnect :: conn -> IO ()Source
Disconnection from the database. Every opened statement must be finished after this method executed.
Explicitly start the transaction. Without starting the transaction you can not commit or rollback it. HDBI does not check if transaction started or not, this is the application's resposibility.
This is not recomended to use start
by hands, use withTransaction
instead
Explicitly commit started transaction. You must start
the transaction
before commit
This is not recomended to use commit
by hands, use withTransaction
instead
rollback :: conn -> IO ()Source
Rollback the transaction's state. You must start
the transaction before
rollback
This is not recomended to use rollback
by hands, use withTransaction
instead
inTransaction :: conn -> IO BoolSource
Check if current connection is in transaction state. Return True if transaction is started. Each driver implements it with it's own way: some RDBMS has API to check transaction state (like PostgreSQL), some has no (like Sqlite3).
connStatus :: conn -> IO ConnStatusSource
Return the current status of connection
prepare :: conn -> Query -> IO (ConnStatement conn)Source
Prepare the statement. Some databases has no feature of preparing statements (PostgreSQL can just prepare named statements), so each driver behaves it's own way.
run :: ToRow row => conn -> Query -> row -> IO ()Source
Run query and safely finalize statement after that. Has default
implementation through execute
.
runMany :: ToRow row => conn -> Query -> [row] -> IO ()Source
Execute query with set of parameters. Has default implementation through
executeMany
.
runRaw :: conn -> Query -> IO ()Source
Run raw query. Many databases has an ablility to run a raw queries
separated by semicolon. Implementation of this method must use this
ability.
Has default implementation through run
clone :: conn -> IO connSource
Clone the database connection. Return new connection with the same settings
hdbiDriverName :: conn -> StringSource
The name of the HDBI driver module for this connection. Ideally would be the same as the database name portion of the Cabal package name. For instance, "sqlite3" or "postgresql". This is the layer that is bound most tightly to HDBI
dbTransactionSupport :: conn -> BoolSource
class Typeable stmt => Statement stmt whereSource
Statement prepared on database side or just in memory
execute :: ToRow row => stmt -> row -> IO ()Source
Execute single query with parameters. In query each parameter must be replaced with ''?'' placeholder. This rule is true for every database, even for PostgreSQL which uses placeholders like ''$1''. Application must ensure that the count of placeholders is equal to count of parameter, it is likely cause an error if it is not.
executeMany :: ToRow row => stmt -> [row] -> IO ()Source
Execute one query many times with a list of paramters. Has default
implementation through execute
.
statementStatus :: stmt -> IO StatementStatusSource
Return the current statement's status.
Finish statement and remove database-specific pointer. No any actions may
be proceeded after closing the statement, excpet statementStatus
which
will return StatementFinished
and reset
.
Reset statement to it's initial state, just like after prepare
.
fetch :: FromRow row => stmt -> IO (Maybe row)Source
Fetch next row from the executed statement. Return Nothing when there is no more results acceptable. Each call return next row from the result.
UPDATE INSERT and DELETE queries will likely return Nothing.
NOTE: You still need to explicitly finish the statement after receiving Nothing, unlike with old HDBC interface.
fetchAll :: FromRow row => stmt -> IO (Seq row)Source
Optional method to strictly fetch all rows from statement. Has default
implementation through fetch
.
getColumnNames :: stmt -> IO [Text]Source
Return list of column names of the result.
getColumnsCount :: stmt -> IO IntSource
Return the number of columns representing the result. Has default
implementation through getColumnNames
originalQuery :: stmt -> QuerySource
Return the original query the statement was prepared from.
Data types
safe newtype wrapper for queries. Just lazy Text inside.
data ConnStatus Source
Connection status
ConnOK | Successfully connected |
ConnDisconnected | Successfully disconnected, all statements must be closed at this state |
ConnBad | Connection is in some bad state |
data ConnWrapper Source
Wrapps the specific connection. You can write database-independent code
mixing it with database-dependent using castConnection
function to cast
Wrapper to specific connection type, if you need.
forall conn . Connection conn => ConnWrapper conn |
data StatementStatus Source
Statement's status returning by function statementStatus
.
StatementNew | Newly created statement |
StatementExecuted | Expression executed, now you can fetch the rows |
StatementFetched | Fetching is done, no more rows can be queried |
StatementFinished | Finished, no more actions with this statement |
data StmtWrapper Source
Wrapper around some specific Statement
instance to write
database-independent code
forall stmt . Statement stmt => StmtWrapper stmt |
Error throwing by driver when database operation fails
SqlError | Internal database error |
| |
SqlDriverError | Driver-specific operational error |
|
Auxiliary functions
castConnection :: Connection conn => ConnWrapper -> Maybe connSource
castStatement :: Statement stmt => StmtWrapper -> Maybe stmtSource
Cast wrapped statement to specific type. You can write database-specific code safely casting wrapped statement to specific type dynamically.
withTransaction :: Connection conn => conn -> IO a -> IO aSource
Execute some code. If any uncaught exception occurs, run
rollback
and re-raise it. Otherwise, run commit
and return.
This function, therefore, encapsulates the logical property that a transaction is all about: all or nothing.
The Connection
object passed in is passed directly to the specified function
as a convenience.
This function traps all uncaught exceptions, not just SqlError
. Therefore,
you will get a rollback for any exception that you don't handle. That's
probably what you want anyway.
If there was an error while running rollback
, this error will not be
reported since the original exception will be propogated back. (You'd probably
like to know about the root cause for all of this anyway.) Feedback
on this behavior is solicited.
:: (Connection conn, Statement stmt, stmt ~ ConnStatement conn) | |
=> conn | Connection |
-> Query | Query string |
-> (stmt -> IO a) | Action at the statement |
-> IO a |
Create statement and execute monadic action using it. Safely finalize Statement after action is done.
runFetch :: (Connection con, ToRow params, FromRow row) => con -> Query -> params -> IO (Maybe row)Source
Run query and return first row
runFetchAll :: (Connection con, ToRow params, FromRow row) => con -> Query -> params -> IO (Seq row)Source
runFetchOne :: (Connection con, ToRow params, FromSql col) => con -> Query -> params -> IO (Maybe col)Source