-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Haskell Database Connectivity
--
-- HDBC provides an abstraction layer between Haskell programs and SQL
-- relational databases. This lets you write database code once, in
-- Haskell, and have it work with any number of backend SQL databases
-- (MySQL, Oracle, PostgreSQL, ODBC-compliant databases, etc.)
@package HDBC
@version 2.4.0.2
module Database.HDBC.Locale
-- | Locale representing American usage.
--
-- knownTimeZones contains only the ten time-zones mentioned in
-- RFC 822 sec. 5: "UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT",
-- "PST", "PDT". Note that the parsing functions will regardless parse
-- single-letter military time-zones and +HHMM format.
defaultTimeLocale :: TimeLocale
-- | As the semantic of System.Locale.iso8601DateFormat has changed with
-- old-locale-1.0.0.2 in a non-compatible way, we now define our own
-- (compatible) version of it.
iso8601DateFormat :: Maybe String -> String
module Database.HDBC.SqlValue
-- | SqlValue is the main type for expressing Haskell values to SQL
-- databases.
--
-- INTRODUCTION TO SQLVALUE
--
-- This type is used to marshall Haskell data to and from database APIs.
-- HDBC driver interfaces will do their best to use the most accurate and
-- efficient way to send a particular value to the database server.
--
-- Values read back from the server are constructed with the most
-- appropriate SqlValue constructor. fromSql or
-- safeFromSql can then be used to convert them into whatever type
-- is needed locally in Haskell.
--
-- Most people will use toSql and fromSql instead of
-- manipulating SqlValues directly.
--
-- EASY CONVERSIONS BETWEEN HASKELL TYPES
--
-- Conversions are powerful; for instance, you can call fromSql on
-- a SqlInt32 and get a String or a Double out of it. This class attempts
-- to Do The Right Thing whenever possible, and will raise an error when
-- asked to do something incorrect. In particular, when converting to any
-- type except a Maybe, SqlNull as the input will cause an error
-- to be raised.
--
-- Conversions are implemented in terms of the Data.Convertible
-- module, part of the convertible package. You can refer to its
-- documentation, and import that module, if you wish to parse the Left
-- result from safeFromSql yourself, or write your own conversion
-- instances.
--
-- Here are some notes about conversion:
--
--
-- - Fractions of a second are not preserved on time values
-- - There is no safeToSql because toSql never
-- fails.
--
--
-- See also toSql, safeFromSql, fromSql,
-- nToSql, iToSql, posixToSql.
--
-- ERROR CONDITIONS
--
-- There may sometimes be an error during conversion. For instance, if
-- you have a SqlString and are attempting to convert it to an
-- Integer, but it doesn't parse as an Integer, you will get an error.
-- This will be indicated as an exception if using fromSql, or a
-- Left result if using safeFromSql.
--
-- SPECIAL NOTE ON POSIXTIME
--
-- Note that a NominalDiffTime or POSIXTime is converted to
-- SqlDiffTime by toSql. HDBC cannot differentiate between
-- NominalDiffTime and POSIXTime since they are the same
-- underlying type. You must construct SqlPOSIXTime manually or
-- via posixToSql, or use SqlUTCTime.
--
-- DETAILS ON SQL TYPES
--
-- HDBC database backends are expected to marshal date and time data back
-- and forth using the appropriate representation for the underlying
-- database engine. Databases such as PostgreSQL with builtin date and
-- time types should see automatic conversion between these Haskell types
-- to database types. Other databases will be presented with an integer
-- or a string. Care should be taken to use the same type on the Haskell
-- side as you use on the database side. For instance, if your database
-- type lacks timezone information, you ought not to use ZonedTime, but
-- instead LocalTime or UTCTime. Database type systems are not always as
-- rich as Haskell. For instance, for data stored in a TIMESTAMP WITHOUT
-- TIME ZONE column, HDBC may not be able to tell if it is intended as
-- UTCTime or LocalTime data, and will happily convert it to both, upon
-- your request. It is your responsibility to ensure that you treat
-- timezone issues with due care.
--
-- This behavior also exists for other types. For instance, many
-- databases do not have a Rational type, so they will just use the show
-- function and store a Rational as a string.
--
-- The conversion between Haskell types and database types is complex,
-- and generic code in HDBC or its backends cannot possibly accomodate
-- every possible situation. In some cases, you may be best served by
-- converting your Haskell type to a String, and passing that to the
-- database.
--
-- UNICODE AND BYTESTRINGS
--
-- Beginning with HDBC v2.0, interactions with a database are presumed to
-- occur in UTF-8.
--
-- To accomplish this, whenever a ByteString must be converted to or from
-- a String, the ByteString is assumed to be in UTF-8 encoding, and will
-- be decoded or encoded as appropriate. Database drivers will generally
-- present text or string data they have received from the database as a
-- SqlValue holding a ByteString, which fromSql will automatically
-- convert to a String, and thus automatically decode UTF-8, when you
-- need it. In the other direction, database drivers will generally
-- convert a SqlString to a ByteString in UTF-8 encoding before
-- passing it to the database engine.
--
-- If you are handling some sort of binary data that is not in UTF-8, you
-- can of course work with the ByteString directly, which will bypass any
-- conversion.
--
-- Due to lack of support by database engines, lazy ByteStrings are not
-- passed to database drivers. When you use toSql on a lazy
-- ByteString, it will be converted to a strict ByteString for storage.
-- Similarly, fromSql will convert a strict ByteString to a lazy
-- ByteString if you demand it.
--
-- EQUALITY OF SQLVALUE
--
-- Two SqlValues are considered to be equal if one of these hold. The
-- first comparison that can be made is controlling; if none of these
-- comparisons can be made, then they are not equal:
--
--
-- - Both are NULL
-- - Both represent the same type and the encapsulated values are
-- considered equal by applying (==) to them
-- - The values of each, when converted to a string, are equal
--
--
-- STRING VERSIONS OF TIMES
--
-- Default string representations are given as comments below where such
-- are non-obvious. These are used for fromSql when a
-- String is desired. They are also defaults for representing data
-- to SQL backends, though individual backends may override them when a
-- different format is demanded by the underlying database. Date and time
-- formats use ISO8601 date format, with HH:MM:SS added for time, and
-- -HHMM added for timezone offsets.
--
-- DEPRECATED CONSTRUCTORS
--
-- SqlEpochTime and SqlTimeDiff are no longer created
-- automatically by any toSql or fromSql functions or
-- database backends. They may still be manually constructed, but are
-- expected to be removed in a future version. Although these two
-- constructures will be removed, support for marshalling to and from the
-- old System.Time data will be maintained as long as System.Time is,
-- simply using the newer data types for conversion.
data SqlValue
SqlString :: String -> SqlValue
SqlByteString :: ByteString -> SqlValue
SqlWord32 :: Word32 -> SqlValue
SqlWord64 :: Word64 -> SqlValue
SqlInt32 :: Int32 -> SqlValue
SqlInt64 :: Int64 -> SqlValue
SqlInteger :: Integer -> SqlValue
SqlChar :: Char -> SqlValue
SqlBool :: Bool -> SqlValue
SqlDouble :: Double -> SqlValue
SqlRational :: Rational -> SqlValue
-- | Local YYYY-MM-DD (no timezone).
SqlLocalDate :: Day -> SqlValue
-- | Local HH:MM:SS (no timezone).
SqlLocalTimeOfDay :: TimeOfDay -> SqlValue
-- | Local HH:MM:SS -HHMM. Converts to and from (TimeOfDay, TimeZone).
SqlZonedLocalTimeOfDay :: TimeOfDay -> TimeZone -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS (no timezone).
SqlLocalTime :: LocalTime -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS -HHMM. Considered equal if both convert to
-- the same UTC time.
SqlZonedTime :: ZonedTime -> SqlValue
-- | UTC YYYY-MM-DD HH:MM:SS.
SqlUTCTime :: UTCTime -> SqlValue
-- | Calendar diff between seconds. Rendered as Integer when converted to
-- String, but greater precision may be preserved for other types or to
-- underlying database.
SqlDiffTime :: NominalDiffTime -> SqlValue
-- | Time as seconds since midnight Jan 1 1970 UTC. Integer rendering as
-- for SqlDiffTime.
SqlPOSIXTime :: POSIXTime -> SqlValue
-- | DEPRECATED Representation of ClockTime or CalendarTime. Use
-- SqlPOSIXTime instead.
SqlEpochTime :: Integer -> SqlValue
-- | DEPRECATED Representation of TimeDiff. Use SqlDiffTime instead.
SqlTimeDiff :: Integer -> SqlValue
-- | NULL in SQL or Nothing in Haskell.
SqlNull :: SqlValue
-- | Conversions to and from SqlValues and standard Haskell types.
--
-- This function converts from an SqlValue to a Haskell value.
-- Many people will use the simpler fromSql instead. This function
-- is simply a restricted-type wrapper around safeConvert.
safeFromSql :: Convertible SqlValue a => SqlValue -> ConvertResult a
-- | Convert a value to an SqlValue. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
toSql :: Convertible a SqlValue => a -> SqlValue
-- | Convert from an SqlValue to a Haskell value. Any problem is
-- indicated by calling error. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
fromSql :: Convertible SqlValue a => SqlValue -> a
-- | Converts any Integral type to a SqlValue by using toInteger.
nToSql :: Integral a => a -> SqlValue
-- | Convenience function for using numeric literals in your program.
iToSql :: Int -> SqlValue
-- | Convenience function for converting POSIXTime to a
-- SqlValue, because toSql cannot do the correct thing in
-- this instance.
posixToSql :: POSIXTime -> SqlValue
instance GHC.Show.Show Database.HDBC.SqlValue.SqlValue
instance GHC.Classes.Eq Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible GHC.Base.String Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Base.String
instance Data.Convertible.Base.Convertible Data.Text.Internal.Text Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Text.Internal.Text
instance Data.Convertible.Base.Convertible Data.Text.Internal.Lazy.Text Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Text.Internal.Lazy.Text
instance Data.Convertible.Base.Convertible Data.ByteString.Internal.ByteString Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.ByteString.Internal.ByteString
instance Data.Convertible.Base.Convertible Data.ByteString.Lazy.Internal.ByteString Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.ByteString.Lazy.Internal.ByteString
instance Data.Convertible.Base.Convertible GHC.Types.Int Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Types.Int
instance Data.Convertible.Base.Convertible GHC.Int.Int32 Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Int.Int32
instance Data.Convertible.Base.Convertible GHC.Int.Int64 Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Int.Int64
instance Data.Convertible.Base.Convertible GHC.Word.Word32 Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Word.Word32
instance Data.Convertible.Base.Convertible GHC.Word.Word64 Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Word.Word64
instance Data.Convertible.Base.Convertible GHC.Integer.Type.Integer Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Integer.Type.Integer
instance Data.Convertible.Base.Convertible GHC.Types.Bool Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Types.Bool
instance Data.Convertible.Base.Convertible GHC.Types.Char Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Types.Char
instance Data.Convertible.Base.Convertible GHC.Types.Double Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Types.Double
instance Data.Convertible.Base.Convertible GHC.Real.Rational Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue GHC.Real.Rational
instance Data.Convertible.Base.Convertible Data.Time.Calendar.Days.Day Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.Calendar.Days.Day
instance Data.Convertible.Base.Convertible Data.Time.LocalTime.TimeOfDay.TimeOfDay Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.LocalTime.TimeOfDay.TimeOfDay
instance Data.Convertible.Base.Convertible (Data.Time.LocalTime.TimeOfDay.TimeOfDay, Data.Time.LocalTime.TimeZone.TimeZone) Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue (Data.Time.LocalTime.TimeOfDay.TimeOfDay, Data.Time.LocalTime.TimeZone.TimeZone)
instance Data.Convertible.Base.Convertible Data.Time.LocalTime.LocalTime.LocalTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.LocalTime.LocalTime.LocalTime
instance Data.Convertible.Base.Convertible Data.Time.LocalTime.LocalTime.ZonedTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.LocalTime.LocalTime.ZonedTime
instance Data.Convertible.Base.Convertible Data.Time.Clock.UTC.UTCTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.Clock.UTC.UTCTime
instance Data.Convertible.Base.Convertible Data.Time.Clock.UTC.NominalDiffTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.Clock.UTC.NominalDiffTime
instance Data.Convertible.Base.Convertible System.Time.ClockTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue System.Time.ClockTime
instance Data.Convertible.Base.Convertible System.Time.TimeDiff Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue System.Time.TimeDiff
instance Data.Convertible.Base.Convertible Data.Time.Clock.Scale.DiffTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue Data.Time.Clock.Scale.DiffTime
instance Data.Convertible.Base.Convertible System.Time.CalendarTime Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue System.Time.CalendarTime
instance Data.Convertible.Base.Convertible a Database.HDBC.SqlValue.SqlValue => Data.Convertible.Base.Convertible (GHC.Base.Maybe a) Database.HDBC.SqlValue.SqlValue
instance Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue a => Data.Convertible.Base.Convertible Database.HDBC.SqlValue.SqlValue (GHC.Base.Maybe a)
-- | Definitions of, and utilities for, specifying what type of data is
-- represented by a column.
--
-- Written by John Goerzen, jgoerzen@complete.org
module Database.HDBC.ColTypes
-- | The description of a column.
--
-- Fields are Nothing if the database backend cannot supply the requested
-- information.
--
-- The colSize field works like this:
--
-- For character types, the maximum width of the column. For numeric
-- types, the total number of digits allowed. See the ODBC manual for
-- more.
--
-- The colOctetLength field is defined for character and binary types,
-- and gives the number of bytes the column requires, regardless of
-- encoding.
data SqlColDesc
SqlColDesc :: SqlTypeId -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Bool -> SqlColDesc
-- | Type of data stored here
[colType] :: SqlColDesc -> SqlTypeId
-- | The size of a column
[colSize] :: SqlColDesc -> Maybe Int
-- | The maximum size in octets
[colOctetLength] :: SqlColDesc -> Maybe Int
-- | Digits to the right of the period
[colDecDigits] :: SqlColDesc -> Maybe Int
-- | Whether NULL is acceptable
[colNullable] :: SqlColDesc -> Maybe Bool
-- | The type identifier for a given column.
--
-- This represents the type of data stored in the column in the
-- underlying SQL engine. It does not form the entire column type; see
-- SqlColDesc for that.
--
-- These types correspond mainly to those defined by ODBC.
data SqlTypeId
-- | Fixed-width character strings
SqlCharT :: SqlTypeId
-- | Variable-width character strings
SqlVarCharT :: SqlTypeId
-- | Variable-width character strings, max length implementation dependant
SqlLongVarCharT :: SqlTypeId
-- | Fixed-width Unicode strings
SqlWCharT :: SqlTypeId
-- | Variable-width Unicode strings
SqlWVarCharT :: SqlTypeId
-- | Variable-width Unicode strings, max length implementation dependant
SqlWLongVarCharT :: SqlTypeId
-- | Signed exact values
SqlDecimalT :: SqlTypeId
-- | Signed exact integer values
SqlNumericT :: SqlTypeId
-- | 16-bit integer values
SqlSmallIntT :: SqlTypeId
-- | 32-bit integer values
SqlIntegerT :: SqlTypeId
SqlRealT :: SqlTypeId
-- | Signed inexact floating-point values
SqlFloatT :: SqlTypeId
-- | Signed inexact double-precision values
SqlDoubleT :: SqlTypeId
-- | A single bit
SqlBitT :: SqlTypeId
-- | 8-bit integer values
SqlTinyIntT :: SqlTypeId
-- | 64-bit integer values
SqlBigIntT :: SqlTypeId
-- | Fixed-length binary data
SqlBinaryT :: SqlTypeId
-- | Variable-length binary data
SqlVarBinaryT :: SqlTypeId
-- | Variable-length binary data, max length implementation dependant
SqlLongVarBinaryT :: SqlTypeId
-- | A date
SqlDateT :: SqlTypeId
-- | A time, no timezone
SqlTimeT :: SqlTypeId
-- | A time, with timezone
SqlTimeWithZoneT :: SqlTypeId
-- | Combined date and time, no timezone
SqlTimestampT :: SqlTypeId
-- | Combined date and time, with timezone
SqlTimestampWithZoneT :: SqlTypeId
-- | UTC date/time
SqlUTCDateTimeT :: SqlTypeId
-- | UTC time
SqlUTCTimeT :: SqlTypeId
-- | A time or date difference
SqlIntervalT :: SqlInterval -> SqlTypeId
-- | Global unique identifier
SqlGUIDT :: SqlTypeId
-- | A type not represented here; implementation-specific information in
-- the String
SqlUnknownT :: String -> SqlTypeId
-- | The different types of intervals in SQL.
data SqlInterval
-- | Difference in months
SqlIntervalMonthT :: SqlInterval
-- | Difference in years
SqlIntervalYearT :: SqlInterval
-- | Difference in years+months
SqlIntervalYearToMonthT :: SqlInterval
-- | Difference in days
SqlIntervalDayT :: SqlInterval
-- | Difference in hours
SqlIntervalHourT :: SqlInterval
-- | Difference in minutes
SqlIntervalMinuteT :: SqlInterval
-- | Difference in seconds
SqlIntervalSecondT :: SqlInterval
-- | Difference in days+hours
SqlIntervalDayToHourT :: SqlInterval
-- | Difference in days+minutes
SqlIntervalDayToMinuteT :: SqlInterval
-- | Difference in days+seconds
SqlIntervalDayToSecondT :: SqlInterval
-- | Difference in hours+minutes
SqlIntervalHourToMinuteT :: SqlInterval
-- | Difference in hours+seconds
SqlIntervalHourToSecondT :: SqlInterval
-- | Difference in minutes+seconds
SqlIntervalMinuteToSecondT :: SqlInterval
instance GHC.Show.Show Database.HDBC.ColTypes.SqlColDesc
instance GHC.Read.Read Database.HDBC.ColTypes.SqlColDesc
instance GHC.Classes.Eq Database.HDBC.ColTypes.SqlColDesc
instance GHC.Read.Read Database.HDBC.ColTypes.SqlTypeId
instance GHC.Show.Show Database.HDBC.ColTypes.SqlTypeId
instance GHC.Classes.Eq Database.HDBC.ColTypes.SqlTypeId
instance GHC.Read.Read Database.HDBC.ColTypes.SqlInterval
instance GHC.Show.Show Database.HDBC.ColTypes.SqlInterval
instance GHC.Classes.Eq Database.HDBC.ColTypes.SqlInterval
module Database.HDBC.Statement
data Statement
Statement :: ([SqlValue] -> IO Integer) -> IO () -> ([[SqlValue]] -> IO ()) -> IO () -> IO (Maybe [SqlValue]) -> IO [String] -> String -> IO [(String, SqlColDesc)] -> 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.
[execute] :: Statement -> [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.
[executeRaw] :: Statement -> 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.
[executeMany] :: Statement -> [[SqlValue]] -> IO ()
-- | Abort a query in progress -- usually not needed.
[finish] :: Statement -> 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.
[fetchRow] :: Statement -> 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.
[getColumnNames] :: Statement -> IO [String]
-- | The original query that this Statement was prepared with.
[originalQuery] :: Statement -> 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 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.
[describeResult] :: Statement -> 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 :: String -> Int -> String -> SqlError
[seState] :: SqlError -> String
[seNativeError] :: SqlError -> Int
[seErrorMsg] :: SqlError -> String
-- | Converts any Integral type to a SqlValue by using toInteger.
nToSql :: Integral a => a -> SqlValue
-- | Convenience function for using numeric literals in your program.
iToSql :: Int -> SqlValue
-- | Convenience function for converting POSIXTime to a
-- SqlValue, because toSql cannot do the correct thing in
-- this instance.
posixToSql :: POSIXTime -> SqlValue
-- | Convert from an SqlValue to a Haskell value. Any problem is
-- indicated by calling error. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
fromSql :: Convertible SqlValue a => SqlValue -> a
-- | Conversions to and from SqlValues and standard Haskell types.
--
-- This function converts from an SqlValue to a Haskell value.
-- Many people will use the simpler fromSql instead. This function
-- is simply a restricted-type wrapper around safeConvert.
safeFromSql :: Convertible SqlValue a => SqlValue -> ConvertResult a
-- | Convert a value to an SqlValue. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
toSql :: Convertible a SqlValue => a -> SqlValue
-- | SqlValue is the main type for expressing Haskell values to SQL
-- databases.
--
-- INTRODUCTION TO SQLVALUE
--
-- This type is used to marshall Haskell data to and from database APIs.
-- HDBC driver interfaces will do their best to use the most accurate and
-- efficient way to send a particular value to the database server.
--
-- Values read back from the server are constructed with the most
-- appropriate SqlValue constructor. fromSql or
-- safeFromSql can then be used to convert them into whatever type
-- is needed locally in Haskell.
--
-- Most people will use toSql and fromSql instead of
-- manipulating SqlValues directly.
--
-- EASY CONVERSIONS BETWEEN HASKELL TYPES
--
-- Conversions are powerful; for instance, you can call fromSql on
-- a SqlInt32 and get a String or a Double out of it. This class attempts
-- to Do The Right Thing whenever possible, and will raise an error when
-- asked to do something incorrect. In particular, when converting to any
-- type except a Maybe, SqlNull as the input will cause an error
-- to be raised.
--
-- Conversions are implemented in terms of the Data.Convertible
-- module, part of the convertible package. You can refer to its
-- documentation, and import that module, if you wish to parse the Left
-- result from safeFromSql yourself, or write your own conversion
-- instances.
--
-- Here are some notes about conversion:
--
--
-- - Fractions of a second are not preserved on time values
-- - There is no safeToSql because toSql never
-- fails.
--
--
-- See also toSql, safeFromSql, fromSql,
-- nToSql, iToSql, posixToSql.
--
-- ERROR CONDITIONS
--
-- There may sometimes be an error during conversion. For instance, if
-- you have a SqlString and are attempting to convert it to an
-- Integer, but it doesn't parse as an Integer, you will get an error.
-- This will be indicated as an exception if using fromSql, or a
-- Left result if using safeFromSql.
--
-- SPECIAL NOTE ON POSIXTIME
--
-- Note that a NominalDiffTime or POSIXTime is converted to
-- SqlDiffTime by toSql. HDBC cannot differentiate between
-- NominalDiffTime and POSIXTime since they are the same
-- underlying type. You must construct SqlPOSIXTime manually or
-- via posixToSql, or use SqlUTCTime.
--
-- DETAILS ON SQL TYPES
--
-- HDBC database backends are expected to marshal date and time data back
-- and forth using the appropriate representation for the underlying
-- database engine. Databases such as PostgreSQL with builtin date and
-- time types should see automatic conversion between these Haskell types
-- to database types. Other databases will be presented with an integer
-- or a string. Care should be taken to use the same type on the Haskell
-- side as you use on the database side. For instance, if your database
-- type lacks timezone information, you ought not to use ZonedTime, but
-- instead LocalTime or UTCTime. Database type systems are not always as
-- rich as Haskell. For instance, for data stored in a TIMESTAMP WITHOUT
-- TIME ZONE column, HDBC may not be able to tell if it is intended as
-- UTCTime or LocalTime data, and will happily convert it to both, upon
-- your request. It is your responsibility to ensure that you treat
-- timezone issues with due care.
--
-- This behavior also exists for other types. For instance, many
-- databases do not have a Rational type, so they will just use the show
-- function and store a Rational as a string.
--
-- The conversion between Haskell types and database types is complex,
-- and generic code in HDBC or its backends cannot possibly accomodate
-- every possible situation. In some cases, you may be best served by
-- converting your Haskell type to a String, and passing that to the
-- database.
--
-- UNICODE AND BYTESTRINGS
--
-- Beginning with HDBC v2.0, interactions with a database are presumed to
-- occur in UTF-8.
--
-- To accomplish this, whenever a ByteString must be converted to or from
-- a String, the ByteString is assumed to be in UTF-8 encoding, and will
-- be decoded or encoded as appropriate. Database drivers will generally
-- present text or string data they have received from the database as a
-- SqlValue holding a ByteString, which fromSql will automatically
-- convert to a String, and thus automatically decode UTF-8, when you
-- need it. In the other direction, database drivers will generally
-- convert a SqlString to a ByteString in UTF-8 encoding before
-- passing it to the database engine.
--
-- If you are handling some sort of binary data that is not in UTF-8, you
-- can of course work with the ByteString directly, which will bypass any
-- conversion.
--
-- Due to lack of support by database engines, lazy ByteStrings are not
-- passed to database drivers. When you use toSql on a lazy
-- ByteString, it will be converted to a strict ByteString for storage.
-- Similarly, fromSql will convert a strict ByteString to a lazy
-- ByteString if you demand it.
--
-- EQUALITY OF SQLVALUE
--
-- Two SqlValues are considered to be equal if one of these hold. The
-- first comparison that can be made is controlling; if none of these
-- comparisons can be made, then they are not equal:
--
--
-- - Both are NULL
-- - Both represent the same type and the encapsulated values are
-- considered equal by applying (==) to them
-- - The values of each, when converted to a string, are equal
--
--
-- STRING VERSIONS OF TIMES
--
-- Default string representations are given as comments below where such
-- are non-obvious. These are used for fromSql when a
-- String is desired. They are also defaults for representing data
-- to SQL backends, though individual backends may override them when a
-- different format is demanded by the underlying database. Date and time
-- formats use ISO8601 date format, with HH:MM:SS added for time, and
-- -HHMM added for timezone offsets.
--
-- DEPRECATED CONSTRUCTORS
--
-- SqlEpochTime and SqlTimeDiff are no longer created
-- automatically by any toSql or fromSql functions or
-- database backends. They may still be manually constructed, but are
-- expected to be removed in a future version. Although these two
-- constructures will be removed, support for marshalling to and from the
-- old System.Time data will be maintained as long as System.Time is,
-- simply using the newer data types for conversion.
data SqlValue
SqlString :: String -> SqlValue
SqlByteString :: ByteString -> SqlValue
SqlWord32 :: Word32 -> SqlValue
SqlWord64 :: Word64 -> SqlValue
SqlInt32 :: Int32 -> SqlValue
SqlInt64 :: Int64 -> SqlValue
SqlInteger :: Integer -> SqlValue
SqlChar :: Char -> SqlValue
SqlBool :: Bool -> SqlValue
SqlDouble :: Double -> SqlValue
SqlRational :: Rational -> SqlValue
-- | Local YYYY-MM-DD (no timezone).
SqlLocalDate :: Day -> SqlValue
-- | Local HH:MM:SS (no timezone).
SqlLocalTimeOfDay :: TimeOfDay -> SqlValue
-- | Local HH:MM:SS -HHMM. Converts to and from (TimeOfDay, TimeZone).
SqlZonedLocalTimeOfDay :: TimeOfDay -> TimeZone -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS (no timezone).
SqlLocalTime :: LocalTime -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS -HHMM. Considered equal if both convert to
-- the same UTC time.
SqlZonedTime :: ZonedTime -> SqlValue
-- | UTC YYYY-MM-DD HH:MM:SS.
SqlUTCTime :: UTCTime -> SqlValue
-- | Calendar diff between seconds. Rendered as Integer when converted to
-- String, but greater precision may be preserved for other types or to
-- underlying database.
SqlDiffTime :: NominalDiffTime -> SqlValue
-- | Time as seconds since midnight Jan 1 1970 UTC. Integer rendering as
-- for SqlDiffTime.
SqlPOSIXTime :: POSIXTime -> SqlValue
-- | DEPRECATED Representation of ClockTime or CalendarTime. Use
-- SqlPOSIXTime instead.
SqlEpochTime :: Integer -> SqlValue
-- | DEPRECATED Representation of TimeDiff. Use SqlDiffTime instead.
SqlTimeDiff :: Integer -> SqlValue
-- | NULL in SQL or Nothing in Haskell.
SqlNull :: SqlValue
instance GHC.Read.Read Database.HDBC.Statement.SqlError
instance GHC.Show.Show Database.HDBC.Statement.SqlError
instance GHC.Classes.Eq Database.HDBC.Statement.SqlError
instance GHC.Exception.Exception Database.HDBC.Statement.SqlError
-- | Types for HDBC.
--
-- Please note: this module is intended for authors of database driver
-- libraries only. Authors of applications using HDBC should use
-- HDBC exclusively.
--
-- Written by John Goerzen, jgoerzen@complete.org
module Database.HDBC.Types
-- | Main database handle object.
--
-- An IConnection object is created by specific functions in the
-- module for an individual database. That is, the connect function --
-- which creates this object -- is not standardized through the HDBC
-- interface.
--
-- A connection is closed by a call to disconnect.
--
-- A call to commit is required to make sure that your changes get
-- committed to the database. In other words, HDBC has no support for
-- autocommit, which we consider an outdated notion.
class IConnection conn where runRaw conn sql = do { sth <- prepare conn sql; _ <- execute sth [] `finally` finish sth; return () }
-- | Disconnect from the remote database.
--
-- You do not need to explicitly close an IConnection object, but you may
-- do so if you so desire. If you don't, the object will disconnect from
-- the database in a sane way when it is garbage-collected. However, a
-- disconnection may raise an error, so you are encouraged to explicitly
-- call disconnect. Also, garbage collection may not run when the
-- program terminates, and some databases really like an explicit
-- disconnect.
--
-- So, bottom line is, you're best off calling disconnect
-- directly, but the world won't end if you forget.
--
-- This function discards any data not committed already. Database driver
-- implementators should explicitly call rollback if their
-- databases don't do this automatically on disconnect.
--
-- Bad Things (TM) could happen if you call this while you have
-- Statements active. In more precise language, the results in
-- such situations are undefined and vary by database. So don't do it.
disconnect :: IConnection conn => conn -> IO ()
-- | Commit any pending data to the database.
--
-- Required to make any changes take effect.
commit :: IConnection conn => conn -> IO ()
-- | Roll back to the state the database was in prior to the last
-- commit or rollback.
rollback :: IConnection conn => conn -> IO ()
-- | Execute an SQL string, which may contain multiple queries. This is
-- intended for situations where you need to run DML or DDL queries and
-- aren't interested in results.
runRaw :: IConnection conn => conn -> String -> IO ()
-- | Execute a single SQL query. Returns the number of rows modified (see
-- execute for details). The second parameter is a list of
-- replacement values, if any.
run :: IConnection conn => conn -> String -> [SqlValue] -> IO Integer
-- | Prepares a statement for execution.
--
-- Question marks in the statement will be replaced by positional
-- parameters in a later call to execute.
--
-- Please note that, depending on the database and the driver, errors in
-- your SQL may be raised either here or by execute. Make sure you
-- handle exceptions both places if necessary.
prepare :: IConnection conn => conn -> String -> IO Statement
-- | Create a new Connection object, pointed at the same server as
-- this object is. This will generally establish a separate physical
-- connection.
--
-- When you wish to establish multiple connections to a single server,
-- the correct way to do so is to establish the first connection with the
-- driver-specific connection function, and then clone it for each
-- additional connection.
--
-- This can be important when a database doesn't provide much thread
-- support itself, and the HDBC driver module must serialize access to a
-- particular database.
--
-- This can also be a handy utility function whenever you need a separate
-- connection to whatever database you are connected to already.
clone :: IConnection conn => conn -> IO conn
-- | The name of the HDBC driver module for this connection. Ideally would
-- be the same as the database name portion of the Cabal package name.
-- For instance, "sqlite3" or "odbc". This is the layer that is bound
-- most tightly to HDBC.
hdbcDriverName :: IConnection conn => conn -> String
-- | The version of the C (or whatever) client library that the HDBC driver
-- module is bound to. The meaning of this is driver-specific. For an
-- ODBC or similar proxying driver, this should be the version of the
-- ODBC library, not the eventual DB client driver.
hdbcClientVer :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the name of the database
-- client/server in use, if available. For others, identical to
-- hdbcDriverName.
proxiedClientName :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the version of the database
-- client in use, if available. For others, identical to
-- hdbcClientVer. This is the next layer out past the HDBC driver.
proxiedClientVer :: IConnection conn => conn -> String
-- | The version of the database server, if available.
dbServerVer :: IConnection conn => conn -> String
-- | Whether or not the current database supports transactions. If False,
-- then commit and rollback should be expected to raise
-- errors.
--
-- MySQL is the only commonly-used database that is known to not support
-- transactions entirely. Please see the MySQL notes in the ODBC driver
-- for more information.
dbTransactionSupport :: IConnection conn => conn -> Bool
-- | The names of all tables accessible by the current connection,
-- excluding special meta-tables (system tables).
--
-- You should expect this to be returned in the same manner as a result
-- from fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
getTables :: IConnection conn => conn -> IO [String]
-- | Obtain information about the columns in a specific table. 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 fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
describeTable :: IConnection conn => conn -> String -> IO [(String, SqlColDesc)]
data Statement
Statement :: ([SqlValue] -> IO Integer) -> IO () -> ([[SqlValue]] -> IO ()) -> IO () -> IO (Maybe [SqlValue]) -> IO [String] -> String -> IO [(String, SqlColDesc)] -> 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.
[execute] :: Statement -> [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.
[executeRaw] :: Statement -> 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.
[executeMany] :: Statement -> [[SqlValue]] -> IO ()
-- | Abort a query in progress -- usually not needed.
[finish] :: Statement -> 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.
[fetchRow] :: Statement -> 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.
[getColumnNames] :: Statement -> IO [String]
-- | The original query that this Statement was prepared with.
[originalQuery] :: Statement -> 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 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.
[describeResult] :: Statement -> 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 :: String -> Int -> String -> SqlError
[seState] :: SqlError -> String
[seNativeError] :: SqlError -> Int
[seErrorMsg] :: SqlError -> String
-- | Converts any Integral type to a SqlValue by using toInteger.
nToSql :: Integral a => a -> SqlValue
-- | Convenience function for using numeric literals in your program.
iToSql :: Int -> SqlValue
-- | Convenience function for converting POSIXTime to a
-- SqlValue, because toSql cannot do the correct thing in
-- this instance.
posixToSql :: POSIXTime -> SqlValue
-- | Convert from an SqlValue to a Haskell value. Any problem is
-- indicated by calling error. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
fromSql :: Convertible SqlValue a => SqlValue -> a
-- | Conversions to and from SqlValues and standard Haskell types.
--
-- This function converts from an SqlValue to a Haskell value.
-- Many people will use the simpler fromSql instead. This function
-- is simply a restricted-type wrapper around safeConvert.
safeFromSql :: Convertible SqlValue a => SqlValue -> ConvertResult a
-- | Convert a value to an SqlValue. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
toSql :: Convertible a SqlValue => a -> SqlValue
-- | SqlValue is the main type for expressing Haskell values to SQL
-- databases.
--
-- INTRODUCTION TO SQLVALUE
--
-- This type is used to marshall Haskell data to and from database APIs.
-- HDBC driver interfaces will do their best to use the most accurate and
-- efficient way to send a particular value to the database server.
--
-- Values read back from the server are constructed with the most
-- appropriate SqlValue constructor. fromSql or
-- safeFromSql can then be used to convert them into whatever type
-- is needed locally in Haskell.
--
-- Most people will use toSql and fromSql instead of
-- manipulating SqlValues directly.
--
-- EASY CONVERSIONS BETWEEN HASKELL TYPES
--
-- Conversions are powerful; for instance, you can call fromSql on
-- a SqlInt32 and get a String or a Double out of it. This class attempts
-- to Do The Right Thing whenever possible, and will raise an error when
-- asked to do something incorrect. In particular, when converting to any
-- type except a Maybe, SqlNull as the input will cause an error
-- to be raised.
--
-- Conversions are implemented in terms of the Data.Convertible
-- module, part of the convertible package. You can refer to its
-- documentation, and import that module, if you wish to parse the Left
-- result from safeFromSql yourself, or write your own conversion
-- instances.
--
-- Here are some notes about conversion:
--
--
-- - Fractions of a second are not preserved on time values
-- - There is no safeToSql because toSql never
-- fails.
--
--
-- See also toSql, safeFromSql, fromSql,
-- nToSql, iToSql, posixToSql.
--
-- ERROR CONDITIONS
--
-- There may sometimes be an error during conversion. For instance, if
-- you have a SqlString and are attempting to convert it to an
-- Integer, but it doesn't parse as an Integer, you will get an error.
-- This will be indicated as an exception if using fromSql, or a
-- Left result if using safeFromSql.
--
-- SPECIAL NOTE ON POSIXTIME
--
-- Note that a NominalDiffTime or POSIXTime is converted to
-- SqlDiffTime by toSql. HDBC cannot differentiate between
-- NominalDiffTime and POSIXTime since they are the same
-- underlying type. You must construct SqlPOSIXTime manually or
-- via posixToSql, or use SqlUTCTime.
--
-- DETAILS ON SQL TYPES
--
-- HDBC database backends are expected to marshal date and time data back
-- and forth using the appropriate representation for the underlying
-- database engine. Databases such as PostgreSQL with builtin date and
-- time types should see automatic conversion between these Haskell types
-- to database types. Other databases will be presented with an integer
-- or a string. Care should be taken to use the same type on the Haskell
-- side as you use on the database side. For instance, if your database
-- type lacks timezone information, you ought not to use ZonedTime, but
-- instead LocalTime or UTCTime. Database type systems are not always as
-- rich as Haskell. For instance, for data stored in a TIMESTAMP WITHOUT
-- TIME ZONE column, HDBC may not be able to tell if it is intended as
-- UTCTime or LocalTime data, and will happily convert it to both, upon
-- your request. It is your responsibility to ensure that you treat
-- timezone issues with due care.
--
-- This behavior also exists for other types. For instance, many
-- databases do not have a Rational type, so they will just use the show
-- function and store a Rational as a string.
--
-- The conversion between Haskell types and database types is complex,
-- and generic code in HDBC or its backends cannot possibly accomodate
-- every possible situation. In some cases, you may be best served by
-- converting your Haskell type to a String, and passing that to the
-- database.
--
-- UNICODE AND BYTESTRINGS
--
-- Beginning with HDBC v2.0, interactions with a database are presumed to
-- occur in UTF-8.
--
-- To accomplish this, whenever a ByteString must be converted to or from
-- a String, the ByteString is assumed to be in UTF-8 encoding, and will
-- be decoded or encoded as appropriate. Database drivers will generally
-- present text or string data they have received from the database as a
-- SqlValue holding a ByteString, which fromSql will automatically
-- convert to a String, and thus automatically decode UTF-8, when you
-- need it. In the other direction, database drivers will generally
-- convert a SqlString to a ByteString in UTF-8 encoding before
-- passing it to the database engine.
--
-- If you are handling some sort of binary data that is not in UTF-8, you
-- can of course work with the ByteString directly, which will bypass any
-- conversion.
--
-- Due to lack of support by database engines, lazy ByteStrings are not
-- passed to database drivers. When you use toSql on a lazy
-- ByteString, it will be converted to a strict ByteString for storage.
-- Similarly, fromSql will convert a strict ByteString to a lazy
-- ByteString if you demand it.
--
-- EQUALITY OF SQLVALUE
--
-- Two SqlValues are considered to be equal if one of these hold. The
-- first comparison that can be made is controlling; if none of these
-- comparisons can be made, then they are not equal:
--
--
-- - Both are NULL
-- - Both represent the same type and the encapsulated values are
-- considered equal by applying (==) to them
-- - The values of each, when converted to a string, are equal
--
--
-- STRING VERSIONS OF TIMES
--
-- Default string representations are given as comments below where such
-- are non-obvious. These are used for fromSql when a
-- String is desired. They are also defaults for representing data
-- to SQL backends, though individual backends may override them when a
-- different format is demanded by the underlying database. Date and time
-- formats use ISO8601 date format, with HH:MM:SS added for time, and
-- -HHMM added for timezone offsets.
--
-- DEPRECATED CONSTRUCTORS
--
-- SqlEpochTime and SqlTimeDiff are no longer created
-- automatically by any toSql or fromSql functions or
-- database backends. They may still be manually constructed, but are
-- expected to be removed in a future version. Although these two
-- constructures will be removed, support for marshalling to and from the
-- old System.Time data will be maintained as long as System.Time is,
-- simply using the newer data types for conversion.
data SqlValue
SqlString :: String -> SqlValue
SqlByteString :: ByteString -> SqlValue
SqlWord32 :: Word32 -> SqlValue
SqlWord64 :: Word64 -> SqlValue
SqlInt32 :: Int32 -> SqlValue
SqlInt64 :: Int64 -> SqlValue
SqlInteger :: Integer -> SqlValue
SqlChar :: Char -> SqlValue
SqlBool :: Bool -> SqlValue
SqlDouble :: Double -> SqlValue
SqlRational :: Rational -> SqlValue
-- | Local YYYY-MM-DD (no timezone).
SqlLocalDate :: Day -> SqlValue
-- | Local HH:MM:SS (no timezone).
SqlLocalTimeOfDay :: TimeOfDay -> SqlValue
-- | Local HH:MM:SS -HHMM. Converts to and from (TimeOfDay, TimeZone).
SqlZonedLocalTimeOfDay :: TimeOfDay -> TimeZone -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS (no timezone).
SqlLocalTime :: LocalTime -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS -HHMM. Considered equal if both convert to
-- the same UTC time.
SqlZonedTime :: ZonedTime -> SqlValue
-- | UTC YYYY-MM-DD HH:MM:SS.
SqlUTCTime :: UTCTime -> SqlValue
-- | Calendar diff between seconds. Rendered as Integer when converted to
-- String, but greater precision may be preserved for other types or to
-- underlying database.
SqlDiffTime :: NominalDiffTime -> SqlValue
-- | Time as seconds since midnight Jan 1 1970 UTC. Integer rendering as
-- for SqlDiffTime.
SqlPOSIXTime :: POSIXTime -> SqlValue
-- | DEPRECATED Representation of ClockTime or CalendarTime. Use
-- SqlPOSIXTime instead.
SqlEpochTime :: Integer -> SqlValue
-- | DEPRECATED Representation of TimeDiff. Use SqlDiffTime instead.
SqlTimeDiff :: Integer -> SqlValue
-- | NULL in SQL or Nothing in Haskell.
SqlNull :: SqlValue
-- | Sometimes, it is annoying to use typeclasses with Haskell's type
-- system. In those situations, you can use a ConnWrapper. You can create
-- one with:
--
--
-- let wrapped = ConnWrapper iconn
--
--
-- You can then use this directly, since a ConnWrapper is also an
-- IConnection. However, you will not be able to use private
-- database functions on it.
--
-- Or, you can use withWConn.
data ConnWrapper
ConnWrapper :: conn -> ConnWrapper
-- | Unwrap a ConnWrapper and pass the embedded IConnection
-- to a function. Example:
--
--
-- withWConn wrapped run $ "SELECT * from foo where bar = 1" []
--
withWConn :: forall b. ConnWrapper -> (forall conn. IConnection conn => conn -> b) -> b
instance Database.HDBC.Types.IConnection Database.HDBC.Types.ConnWrapper
-- | Utilities for database backend drivers.
--
-- Please note: this module is intended for authors of database driver
-- libraries only. Authors of applications using HDBC should use
-- HDBC exclusively.
--
-- Written by John Goerzen, jgoerzen@complete.org
module Database.HDBC.DriverUtils
type ChildList = MVar [Weak Statement]
-- | Close all children. Intended to be called by the disconnect
-- function in Connection.
--
-- There may be a potential race condition wherein a call to newSth at
-- the same time as a call to this function may result in the new child
-- not being closed.
closeAllChildren :: ChildList -> IO ()
-- | Adds a new child to the existing list. Also takes care of registering
-- a finalizer for it, to remove it from the list when possible.
addChild :: ChildList -> Statement -> IO ()
-- | Welcome to HDBC, the Haskell Database Connectivity library.
--
-- Written by John Goerzen, jgoerzen@complete.org
module Database.HDBC
-- | SqlValue is the main type for expressing Haskell values to SQL
-- databases.
--
-- INTRODUCTION TO SQLVALUE
--
-- This type is used to marshall Haskell data to and from database APIs.
-- HDBC driver interfaces will do their best to use the most accurate and
-- efficient way to send a particular value to the database server.
--
-- Values read back from the server are constructed with the most
-- appropriate SqlValue constructor. fromSql or
-- safeFromSql can then be used to convert them into whatever type
-- is needed locally in Haskell.
--
-- Most people will use toSql and fromSql instead of
-- manipulating SqlValues directly.
--
-- EASY CONVERSIONS BETWEEN HASKELL TYPES
--
-- Conversions are powerful; for instance, you can call fromSql on
-- a SqlInt32 and get a String or a Double out of it. This class attempts
-- to Do The Right Thing whenever possible, and will raise an error when
-- asked to do something incorrect. In particular, when converting to any
-- type except a Maybe, SqlNull as the input will cause an error
-- to be raised.
--
-- Conversions are implemented in terms of the Data.Convertible
-- module, part of the convertible package. You can refer to its
-- documentation, and import that module, if you wish to parse the Left
-- result from safeFromSql yourself, or write your own conversion
-- instances.
--
-- Here are some notes about conversion:
--
--
-- - Fractions of a second are not preserved on time values
-- - There is no safeToSql because toSql never
-- fails.
--
--
-- See also toSql, safeFromSql, fromSql,
-- nToSql, iToSql, posixToSql.
--
-- ERROR CONDITIONS
--
-- There may sometimes be an error during conversion. For instance, if
-- you have a SqlString and are attempting to convert it to an
-- Integer, but it doesn't parse as an Integer, you will get an error.
-- This will be indicated as an exception if using fromSql, or a
-- Left result if using safeFromSql.
--
-- SPECIAL NOTE ON POSIXTIME
--
-- Note that a NominalDiffTime or POSIXTime is converted to
-- SqlDiffTime by toSql. HDBC cannot differentiate between
-- NominalDiffTime and POSIXTime since they are the same
-- underlying type. You must construct SqlPOSIXTime manually or
-- via posixToSql, or use SqlUTCTime.
--
-- DETAILS ON SQL TYPES
--
-- HDBC database backends are expected to marshal date and time data back
-- and forth using the appropriate representation for the underlying
-- database engine. Databases such as PostgreSQL with builtin date and
-- time types should see automatic conversion between these Haskell types
-- to database types. Other databases will be presented with an integer
-- or a string. Care should be taken to use the same type on the Haskell
-- side as you use on the database side. For instance, if your database
-- type lacks timezone information, you ought not to use ZonedTime, but
-- instead LocalTime or UTCTime. Database type systems are not always as
-- rich as Haskell. For instance, for data stored in a TIMESTAMP WITHOUT
-- TIME ZONE column, HDBC may not be able to tell if it is intended as
-- UTCTime or LocalTime data, and will happily convert it to both, upon
-- your request. It is your responsibility to ensure that you treat
-- timezone issues with due care.
--
-- This behavior also exists for other types. For instance, many
-- databases do not have a Rational type, so they will just use the show
-- function and store a Rational as a string.
--
-- The conversion between Haskell types and database types is complex,
-- and generic code in HDBC or its backends cannot possibly accomodate
-- every possible situation. In some cases, you may be best served by
-- converting your Haskell type to a String, and passing that to the
-- database.
--
-- UNICODE AND BYTESTRINGS
--
-- Beginning with HDBC v2.0, interactions with a database are presumed to
-- occur in UTF-8.
--
-- To accomplish this, whenever a ByteString must be converted to or from
-- a String, the ByteString is assumed to be in UTF-8 encoding, and will
-- be decoded or encoded as appropriate. Database drivers will generally
-- present text or string data they have received from the database as a
-- SqlValue holding a ByteString, which fromSql will automatically
-- convert to a String, and thus automatically decode UTF-8, when you
-- need it. In the other direction, database drivers will generally
-- convert a SqlString to a ByteString in UTF-8 encoding before
-- passing it to the database engine.
--
-- If you are handling some sort of binary data that is not in UTF-8, you
-- can of course work with the ByteString directly, which will bypass any
-- conversion.
--
-- Due to lack of support by database engines, lazy ByteStrings are not
-- passed to database drivers. When you use toSql on a lazy
-- ByteString, it will be converted to a strict ByteString for storage.
-- Similarly, fromSql will convert a strict ByteString to a lazy
-- ByteString if you demand it.
--
-- EQUALITY OF SQLVALUE
--
-- Two SqlValues are considered to be equal if one of these hold. The
-- first comparison that can be made is controlling; if none of these
-- comparisons can be made, then they are not equal:
--
--
-- - Both are NULL
-- - Both represent the same type and the encapsulated values are
-- considered equal by applying (==) to them
-- - The values of each, when converted to a string, are equal
--
--
-- STRING VERSIONS OF TIMES
--
-- Default string representations are given as comments below where such
-- are non-obvious. These are used for fromSql when a
-- String is desired. They are also defaults for representing data
-- to SQL backends, though individual backends may override them when a
-- different format is demanded by the underlying database. Date and time
-- formats use ISO8601 date format, with HH:MM:SS added for time, and
-- -HHMM added for timezone offsets.
--
-- DEPRECATED CONSTRUCTORS
--
-- SqlEpochTime and SqlTimeDiff are no longer created
-- automatically by any toSql or fromSql functions or
-- database backends. They may still be manually constructed, but are
-- expected to be removed in a future version. Although these two
-- constructures will be removed, support for marshalling to and from the
-- old System.Time data will be maintained as long as System.Time is,
-- simply using the newer data types for conversion.
data SqlValue
SqlString :: String -> SqlValue
SqlByteString :: ByteString -> SqlValue
SqlWord32 :: Word32 -> SqlValue
SqlWord64 :: Word64 -> SqlValue
SqlInt32 :: Int32 -> SqlValue
SqlInt64 :: Int64 -> SqlValue
SqlInteger :: Integer -> SqlValue
SqlChar :: Char -> SqlValue
SqlBool :: Bool -> SqlValue
SqlDouble :: Double -> SqlValue
SqlRational :: Rational -> SqlValue
-- | Local YYYY-MM-DD (no timezone).
SqlLocalDate :: Day -> SqlValue
-- | Local HH:MM:SS (no timezone).
SqlLocalTimeOfDay :: TimeOfDay -> SqlValue
-- | Local HH:MM:SS -HHMM. Converts to and from (TimeOfDay, TimeZone).
SqlZonedLocalTimeOfDay :: TimeOfDay -> TimeZone -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS (no timezone).
SqlLocalTime :: LocalTime -> SqlValue
-- | Local YYYY-MM-DD HH:MM:SS -HHMM. Considered equal if both convert to
-- the same UTC time.
SqlZonedTime :: ZonedTime -> SqlValue
-- | UTC YYYY-MM-DD HH:MM:SS.
SqlUTCTime :: UTCTime -> SqlValue
-- | Calendar diff between seconds. Rendered as Integer when converted to
-- String, but greater precision may be preserved for other types or to
-- underlying database.
SqlDiffTime :: NominalDiffTime -> SqlValue
-- | Time as seconds since midnight Jan 1 1970 UTC. Integer rendering as
-- for SqlDiffTime.
SqlPOSIXTime :: POSIXTime -> SqlValue
-- | DEPRECATED Representation of ClockTime or CalendarTime. Use
-- SqlPOSIXTime instead.
SqlEpochTime :: Integer -> SqlValue
-- | DEPRECATED Representation of TimeDiff. Use SqlDiffTime instead.
SqlTimeDiff :: Integer -> SqlValue
-- | NULL in SQL or Nothing in Haskell.
SqlNull :: SqlValue
-- | Convert a value to an SqlValue. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
toSql :: Convertible a SqlValue => a -> SqlValue
-- | Convert from an SqlValue to a Haskell value. Any problem is
-- indicated by calling error. This function is simply a
-- restricted-type wrapper around convert. See extended notes on
-- SqlValue.
fromSql :: Convertible SqlValue a => SqlValue -> a
-- | Conversions to and from SqlValues and standard Haskell types.
--
-- This function converts from an SqlValue to a Haskell value.
-- Many people will use the simpler fromSql instead. This function
-- is simply a restricted-type wrapper around safeConvert.
safeFromSql :: Convertible SqlValue a => SqlValue -> ConvertResult a
-- | Converts any Integral type to a SqlValue by using toInteger.
nToSql :: Integral a => a -> SqlValue
-- | Convenience function for using numeric literals in your program.
iToSql :: Int -> SqlValue
-- | Convenience function for converting POSIXTime to a
-- SqlValue, because toSql cannot do the correct thing in
-- this instance.
posixToSql :: POSIXTime -> SqlValue
-- | Main database handle object.
--
-- An IConnection object is created by specific functions in the
-- module for an individual database. That is, the connect function --
-- which creates this object -- is not standardized through the HDBC
-- interface.
--
-- A connection is closed by a call to disconnect.
--
-- A call to commit is required to make sure that your changes get
-- committed to the database. In other words, HDBC has no support for
-- autocommit, which we consider an outdated notion.
class IConnection conn where runRaw conn sql = do { sth <- prepare conn sql; _ <- execute sth [] `finally` finish sth; return () }
-- | Disconnect from the remote database.
--
-- You do not need to explicitly close an IConnection object, but you may
-- do so if you so desire. If you don't, the object will disconnect from
-- the database in a sane way when it is garbage-collected. However, a
-- disconnection may raise an error, so you are encouraged to explicitly
-- call disconnect. Also, garbage collection may not run when the
-- program terminates, and some databases really like an explicit
-- disconnect.
--
-- So, bottom line is, you're best off calling disconnect
-- directly, but the world won't end if you forget.
--
-- This function discards any data not committed already. Database driver
-- implementators should explicitly call rollback if their
-- databases don't do this automatically on disconnect.
--
-- Bad Things (TM) could happen if you call this while you have
-- Statements active. In more precise language, the results in
-- such situations are undefined and vary by database. So don't do it.
disconnect :: IConnection conn => conn -> IO ()
-- | Commit any pending data to the database.
--
-- Required to make any changes take effect.
commit :: IConnection conn => conn -> IO ()
-- | Roll back to the state the database was in prior to the last
-- commit or rollback.
rollback :: IConnection conn => conn -> IO ()
-- | Execute an SQL string, which may contain multiple queries. This is
-- intended for situations where you need to run DML or DDL queries and
-- aren't interested in results.
runRaw :: IConnection conn => conn -> String -> IO ()
-- | Execute a single SQL query. Returns the number of rows modified (see
-- execute for details). The second parameter is a list of
-- replacement values, if any.
run :: IConnection conn => conn -> String -> [SqlValue] -> IO Integer
-- | Prepares a statement for execution.
--
-- Question marks in the statement will be replaced by positional
-- parameters in a later call to execute.
--
-- Please note that, depending on the database and the driver, errors in
-- your SQL may be raised either here or by execute. Make sure you
-- handle exceptions both places if necessary.
prepare :: IConnection conn => conn -> String -> IO Statement
-- | Create a new Connection object, pointed at the same server as
-- this object is. This will generally establish a separate physical
-- connection.
--
-- When you wish to establish multiple connections to a single server,
-- the correct way to do so is to establish the first connection with the
-- driver-specific connection function, and then clone it for each
-- additional connection.
--
-- This can be important when a database doesn't provide much thread
-- support itself, and the HDBC driver module must serialize access to a
-- particular database.
--
-- This can also be a handy utility function whenever you need a separate
-- connection to whatever database you are connected to already.
clone :: IConnection conn => conn -> IO conn
-- | The name of the HDBC driver module for this connection. Ideally would
-- be the same as the database name portion of the Cabal package name.
-- For instance, "sqlite3" or "odbc". This is the layer that is bound
-- most tightly to HDBC.
hdbcDriverName :: IConnection conn => conn -> String
-- | The version of the C (or whatever) client library that the HDBC driver
-- module is bound to. The meaning of this is driver-specific. For an
-- ODBC or similar proxying driver, this should be the version of the
-- ODBC library, not the eventual DB client driver.
hdbcClientVer :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the name of the database
-- client/server in use, if available. For others, identical to
-- hdbcDriverName.
proxiedClientName :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the version of the database
-- client in use, if available. For others, identical to
-- hdbcClientVer. This is the next layer out past the HDBC driver.
proxiedClientVer :: IConnection conn => conn -> String
-- | The version of the database server, if available.
dbServerVer :: IConnection conn => conn -> String
-- | Whether or not the current database supports transactions. If False,
-- then commit and rollback should be expected to raise
-- errors.
--
-- MySQL is the only commonly-used database that is known to not support
-- transactions entirely. Please see the MySQL notes in the ODBC driver
-- for more information.
dbTransactionSupport :: IConnection conn => conn -> Bool
-- | The names of all tables accessible by the current connection,
-- excluding special meta-tables (system tables).
--
-- You should expect this to be returned in the same manner as a result
-- from fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
getTables :: IConnection conn => conn -> IO [String]
-- | Obtain information about the columns in a specific table. 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 fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
describeTable :: IConnection conn => conn -> String -> IO [(String, SqlColDesc)]
-- | Disconnect from the remote database.
--
-- You do not need to explicitly close an IConnection object, but you may
-- do so if you so desire. If you don't, the object will disconnect from
-- the database in a sane way when it is garbage-collected. However, a
-- disconnection may raise an error, so you are encouraged to explicitly
-- call disconnect. Also, garbage collection may not run when the
-- program terminates, and some databases really like an explicit
-- disconnect.
--
-- So, bottom line is, you're best off calling disconnect
-- directly, but the world won't end if you forget.
--
-- This function discards any data not committed already. Database driver
-- implementators should explicitly call rollback if their
-- databases don't do this automatically on disconnect.
--
-- Bad Things (TM) could happen if you call this while you have
-- Statements active. In more precise language, the results in
-- such situations are undefined and vary by database. So don't do it.
disconnect :: IConnection conn => conn -> IO ()
-- | Create a new Connection object, pointed at the same server as
-- this object is. This will generally establish a separate physical
-- connection.
--
-- When you wish to establish multiple connections to a single server,
-- the correct way to do so is to establish the first connection with the
-- driver-specific connection function, and then clone it for each
-- additional connection.
--
-- This can be important when a database doesn't provide much thread
-- support itself, and the HDBC driver module must serialize access to a
-- particular database.
--
-- This can also be a handy utility function whenever you need a separate
-- connection to whatever database you are connected to already.
clone :: IConnection conn => conn -> IO conn
-- | Sometimes, it is annoying to use typeclasses with Haskell's type
-- system. In those situations, you can use a ConnWrapper. You can create
-- one with:
--
--
-- let wrapped = ConnWrapper iconn
--
--
-- You can then use this directly, since a ConnWrapper is also an
-- IConnection. However, you will not be able to use private
-- database functions on it.
--
-- Or, you can use withWConn.
data ConnWrapper
ConnWrapper :: conn -> ConnWrapper
-- | Unwrap a ConnWrapper and pass the embedded IConnection
-- to a function. Example:
--
--
-- withWConn wrapped run $ "SELECT * from foo where bar = 1" []
--
withWConn :: forall b. ConnWrapper -> (forall conn. IConnection conn => conn -> b) -> b
-- | Execute a single SQL query. Returns the number of rows modified (see
-- execute for details). The second parameter is a list of
-- replacement values, if any.
run :: IConnection conn => conn -> String -> [SqlValue] -> IO Integer
-- | Execute an SQL string, which may contain multiple queries. This is
-- intended for situations where you need to run DML or DDL queries and
-- aren't interested in results.
runRaw :: IConnection conn => conn -> String -> IO ()
-- | Like run, but take a list of Maybe Strings instead of
-- SqlValues.
sRun :: IConnection conn => conn -> String -> [Maybe String] -> IO Integer
-- | Prepares a statement for execution.
--
-- Question marks in the statement will be replaced by positional
-- parameters in a later call to execute.
--
-- Please note that, depending on the database and the driver, errors in
-- your SQL may be raised either here or by execute. Make sure you
-- handle exceptions both places if necessary.
prepare :: IConnection conn => conn -> String -> IO Statement
-- | Strict version of quickQuery.
quickQuery' :: IConnection conn => conn -> String -> [SqlValue] -> IO [[SqlValue]]
-- | A quick way to do a query. Similar to preparing, executing, and then
-- calling fetchAllRows on a statement. See also
-- quickQuery'.
quickQuery :: IConnection conn => conn -> String -> [SqlValue] -> IO [[SqlValue]]
-- | Commit any pending data to the database.
--
-- Required to make any changes take effect.
commit :: IConnection conn => conn -> IO ()
-- | Roll back to the state the database was in prior to the last
-- commit or rollback.
rollback :: IConnection conn => conn -> IO ()
-- | 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 IConnection object passed in is passed directly to the
-- specified function as a convenience.
--
-- This function traps all uncaught exceptions, not just
-- SqlErrors. Therefore, you will get a rollback for any exception that
-- you don't handle. That's probably what you want anyway.
--
-- Since all operations in HDBC are done in a transaction, this function
-- doesn't issue an explicit "begin" to the server. You should ideally
-- have called commit or rollback before calling this
-- function. If you haven't, this function will commit or rollback more
-- than just the changes made in the included action.
--
-- 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.
withTransaction :: IConnection conn => conn -> (conn -> IO a) -> IO a
-- | The name of the HDBC driver module for this connection. Ideally would
-- be the same as the database name portion of the Cabal package name.
-- For instance, "sqlite3" or "odbc". This is the layer that is bound
-- most tightly to HDBC.
hdbcDriverName :: IConnection conn => conn -> String
-- | The version of the C (or whatever) client library that the HDBC driver
-- module is bound to. The meaning of this is driver-specific. For an
-- ODBC or similar proxying driver, this should be the version of the
-- ODBC library, not the eventual DB client driver.
hdbcClientVer :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the name of the database
-- client/server in use, if available. For others, identical to
-- hdbcDriverName.
proxiedClientName :: IConnection conn => conn -> String
-- | In the case of a system such as ODBC, the version of the database
-- client in use, if available. For others, identical to
-- hdbcClientVer. This is the next layer out past the HDBC driver.
proxiedClientVer :: IConnection conn => conn -> String
-- | The version of the database server, if available.
dbServerVer :: IConnection conn => conn -> String
-- | Whether or not the current database supports transactions. If False,
-- then commit and rollback should be expected to raise
-- errors.
--
-- MySQL is the only commonly-used database that is known to not support
-- transactions entirely. Please see the MySQL notes in the ODBC driver
-- for more information.
dbTransactionSupport :: IConnection conn => conn -> Bool
-- | The names of all tables accessible by the current connection,
-- excluding special meta-tables (system tables).
--
-- You should expect this to be returned in the same manner as a result
-- from fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
getTables :: IConnection conn => conn -> IO [String]
-- | Obtain information about the columns in a specific table. 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 fetchAllRows'.
--
-- All results should be converted to lowercase for you before you see
-- them.
describeTable :: IConnection conn => conn -> String -> IO [(String, SqlColDesc)]
data 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.
execute :: Statement -> [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.
executeRaw :: Statement -> IO ()
-- | Like execute, but take a list of Maybe Strings instead of
-- SqlValues.
sExecute :: Statement -> [Maybe String] -> IO Integer
-- | 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.
executeMany :: Statement -> [[SqlValue]] -> IO ()
-- | Like executeMany, but take a list of Maybe Strings instead of
-- SqlValues.
sExecuteMany :: Statement -> [[Maybe String]] -> 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.
fetchRow :: Statement -> IO (Maybe [SqlValue])
-- | Like fetchRow, but instead of returning a list, return an
-- association list from column name to value.
--
-- The keys of the column names are lowercase versions of the data
-- returned by getColumnNames. Please heed the warnings there.
-- Additionally, results are undefined if multiple columns are returned
-- with identical names.
fetchRowAL :: Statement -> IO (Maybe [(String, SqlValue)])
-- | Similar to fetchRowAL, but return a Map instead of an
-- association list.
fetchRowMap :: Statement -> IO (Maybe (Map String SqlValue))
-- | Like fetchRow, but return a list of Maybe Strings instead of
-- SqlValues.
sFetchRow :: Statement -> IO (Maybe [Maybe String])
-- | Lazily fetch all rows from an executed Statement.
--
-- You can think of this as hGetContents applied to a database result
-- set.
--
-- The result of this is a lazy list, and each new row will be read,
-- lazily, from the database as the list is processed.
--
-- When you have exhausted the list, the Statement will be
-- finished.
--
-- Please note that the careless use of this function can lead to some
-- unpleasant behavior. In particular, if you have not consumed the
-- entire list, then attempt to finish or re-execute the
-- statement, and then attempt to consume more elements from the list,
-- the result will almost certainly not be what you want.
--
-- But then, similar caveats apply with hGetContents.
--
-- Bottom line: this is a very convenient abstraction; use it wisely.
--
-- Use fetchAllRows' if you need something that is strict, without
-- all these caveats.
fetchAllRows :: Statement -> IO [[SqlValue]]
-- | Strict version of fetchAllRows. Does not have the side-effects
-- of fetchAllRows, but forces the entire result set to be
-- buffered in memory.
fetchAllRows' :: Statement -> IO [[SqlValue]]
-- | Like fetchAllRows, but instead of returning a list for each
-- row, return an association list for each row, from column name to
-- value.
--
-- See fetchRowAL for more details.
fetchAllRowsAL :: Statement -> IO [[(String, SqlValue)]]
-- | Strict version of fetchAllRowsAL
fetchAllRowsAL' :: Statement -> IO [[(String, SqlValue)]]
-- | Like fetchAllRowsAL, but return a list of Maps instead of a
-- list of association lists.
fetchAllRowsMap :: Statement -> IO [Map String SqlValue]
-- | Strict version of fetchAllRowsMap
fetchAllRowsMap' :: Statement -> IO [Map String SqlValue]
-- | Like fetchAllRows, but return Maybe Strings instead of
-- SqlValues.
sFetchAllRows :: Statement -> IO [[Maybe String]]
-- | Strict version of sFetchAllRows.
sFetchAllRows' :: Statement -> IO [[Maybe String]]
-- | 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.
getColumnNames :: Statement -> IO [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 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.
describeResult :: Statement -> IO [(String, SqlColDesc)]
-- | Abort a query in progress -- usually not needed.
finish :: Statement -> IO ()
-- | The original query that this Statement was prepared with.
originalQuery :: Statement -> String
-- | 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 :: String -> Int -> String -> SqlError
[seState] :: SqlError -> String
[seNativeError] :: SqlError -> Int
[seErrorMsg] :: SqlError -> String
-- | A utility function to throw a SqlError. The mechanics of
-- throwing such a thing differ between GHC 6.8.x, Hugs, and GHC 6.10.
-- This function takes care of the special cases to make it simpler.
--
-- With GHC 6.10, it is a type-restricted alias for throw. On all other
-- systems, it is a type-restricted alias for throwDyn.
throwSqlError :: SqlError -> IO a
-- | Execute the given IO action.
--
-- If it raises a SqlError, then execute the supplied handler and
-- return its return value. Otherwise, proceed as normal.
catchSql :: IO a -> (SqlError -> IO a) -> IO a
-- | Like catchSql, with the order of arguments reversed.
handleSql :: (SqlError -> IO a) -> IO a -> IO a
-- | Given an Exception, return Just SqlError if it was an SqlError, or
-- Nothing otherwise. Useful with functions like catchJust.
sqlExceptions :: SqlError -> Maybe SqlError
-- | Catches SqlErrors, and re-raises them as IO errors with fail.
-- Useful if you don't care to catch SQL errors, but want to see a sane
-- error message if one happens. One would often use this as a high-level
-- wrapper around SQL calls.
handleSqlError :: IO a -> IO a