    {-# LANGUAGE DeriveDataTypeable #-}
    module Database.HDBC.Statement
        (
        Statement(..),
        SqlError(..),

        -- * Re-exported from "Database.HDBC.SqlValue"; this re-exporting is deprecated
        nToSql, iToSql, posixToSql, fromSql, safeFromSql, toSql,
        SqlValue(..)
        )

    where
    import Data.Dynamic
    import Database.HDBC.ColTypes
    import Database.HDBC.SqlValue
    import Control.Exception

    data Statement = Statement
        {
         {- | Execute the prepared statement, passing in the given positional
            parameters (that should take the place of the question marks
            in the call to 'prepare').

            For non-SELECT queries, the return value is the number of
            rows modified, if known.  If no rows were modified, you get 0.
            If the value is unknown, you get -1.  All current HDBC drivers
            support this function and should never return -1.

            For SELECT queries, you will always get 0.

            This function should automatically call finish() to finish the previous
            execution, if necessary.
            -}
         Statement -> [SqlValue] -> IO Integer
    execute :: [SqlValue] -> IO Integer,

         {- | Execute the statement as-is, without supplying any
            positional parameters.  This is intended for statements for
            which the results aren't interesting or present (e.g., DDL or
            DML commands).  If your query contains placeholders, this will
            certainly fail; use 'execute' instead. -}
         Statement -> IO ()
    executeRaw :: IO (),

         {- | Execute the query with many rows.
            The return value is the return value from the final row
            as if you had called 'execute' on it.

            Due to optimizations that are possible due to different
            databases and driver designs, this can often be significantly
            faster than using 'execute' multiple times since queries
            need to be compiled only once.

            This is most useful for non-SELECT statements. -}
         Statement -> [[SqlValue]] -> IO ()
    executeMany :: [[SqlValue]] -> IO (),

         {- | Abort a query in progress -- usually not needed. -}
         Statement -> IO ()
    finish :: IO (),

         {- | Fetches one row from the DB.  Returns 'Nothing' if there
            are no more rows.  Will automatically call 'finish' when
            the last row is read. -}
         Statement -> IO (Maybe [SqlValue])
    fetchRow :: IO (Maybe [SqlValue]),

         {- | Returns a list of the column names in the result.
            For maximum portability, you should not assume that
            information is available until after an 'execute' function
            has been run.

            Information is returned here directly as returned
            by the underlying database layer.  Note that different
            databases have different rules about capitalization
            of return values and about representation of names
            of columns that are not simple columns.  For this reason,
            it is suggested that you treat this information for
            display purposes only.  Failing that, you should convert
            to lower (or upper) case, and use @AS@ clauses for
            anything other than simple columns.

            A simple getColumnNames implementation could simply
            apply @map fst@ to the return value of 'describeResult'.
            -}
         Statement -> IO [String]
    getColumnNames :: IO [String],

         {- | The original query that this 'Statement' was prepared
              with. -}
         Statement -> String
    originalQuery :: String,
         {- | Obtain information about the columns in the result set.
              Must be run only after 'execute'.  The String in the result
              set is the column name.

              You should expect this to be returned in the same manner
              as a result from 'Database.HDBC.fetchAllRows''.

              All results should be converted to lowercase for you
              before you see them.

              Please see caveats under 'getColumnNames' for information
              on the column name field here.
     -}
         Statement -> IO [(String, SqlColDesc)]
    describeResult :: IO [(String, SqlColDesc)]
        }

    {- | The main HDBC exception object.  As much information as possible
    is passed from the database through to the application through this object.

    Errors generated in the Haskell layer will have seNativeError set to -1.
    -}
    data SqlError = SqlError {SqlError -> String
    seState :: String,
                              SqlError -> Int
    seNativeError :: Int,
                              SqlError -> String
    seErrorMsg :: String}
                    deriving (SqlError -> SqlError -> Bool
    (SqlError -> SqlError -> Bool)
    -> (SqlError -> SqlError -> Bool) -> Eq SqlError
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SqlError -> SqlError -> Bool
    == :: SqlError -> SqlError -> Bool
    $c/= :: SqlError -> SqlError -> Bool
    /= :: SqlError -> SqlError -> Bool
    Eq, Int -> SqlError -> ShowS
    [SqlError] -> ShowS
    SqlError -> String
    (Int -> SqlError -> ShowS)
    -> (SqlError -> String) -> ([SqlError] -> ShowS) -> Show SqlError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SqlError -> ShowS
    showsPrec :: Int -> SqlError -> ShowS
    $cshow :: SqlError -> String
    show :: SqlError -> String
    $cshowList :: [SqlError] -> ShowS
    showList :: [SqlError] -> ShowS
    Show, ReadPrec [SqlError]
    ReadPrec SqlError
    Int -> ReadS SqlError
    ReadS [SqlError]
    (Int -> ReadS SqlError)
    -> ReadS [SqlError]
    -> ReadPrec SqlError
    -> ReadPrec [SqlError]
    -> Read SqlError
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS SqlError
    readsPrec :: Int -> ReadS SqlError
    $creadList :: ReadS [SqlError]
    readList :: ReadS [SqlError]
    $creadPrec :: ReadPrec SqlError
    readPrec :: ReadPrec SqlError
    $creadListPrec :: ReadPrec [SqlError]
    readListPrec :: ReadPrec [SqlError]
    Read, Typeable)

    #if __GLASGOW_HASKELL__ >= 610
    --data SqlException
    instance Exception SqlError where
    {-
        toException = SomeException
        fromException (SomeException e) = Just e
        fromException _ = Nothing
    -}
    #endif