-- 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.2.5
module Database.HDBC.Locale
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 he 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 Show SqlValue
instance (Convertible SqlValue a) => Convertible SqlValue (Maybe a)
instance (Convertible a SqlValue) => Convertible (Maybe a) SqlValue
instance Convertible SqlValue CalendarTime
instance Convertible CalendarTime SqlValue
instance Convertible SqlValue DiffTime
instance Convertible DiffTime SqlValue
instance Convertible SqlValue TimeDiff
instance Convertible TimeDiff SqlValue
instance Convertible SqlValue ClockTime
instance Convertible ClockTime SqlValue
instance Convertible SqlValue NominalDiffTime
instance Convertible NominalDiffTime SqlValue
instance Convertible SqlValue UTCTime
instance Convertible UTCTime SqlValue
instance Convertible SqlValue ZonedTime
instance Convertible ZonedTime SqlValue
instance Convertible SqlValue LocalTime
instance Convertible LocalTime SqlValue
instance Convertible SqlValue (TimeOfDay, TimeZone)
instance Convertible (TimeOfDay, TimeZone) SqlValue
instance Convertible SqlValue TimeOfDay
instance Convertible TimeOfDay SqlValue
instance Convertible SqlValue Day
instance Convertible Day SqlValue
instance Typeable TimeDiff
instance Typeable ClockTime
instance Convertible SqlValue Rational
instance Convertible Rational SqlValue
instance Convertible SqlValue Double
instance Convertible Double SqlValue
instance Convertible SqlValue Char
instance Convertible Char SqlValue
instance Convertible SqlValue Bool
instance Convertible Bool SqlValue
instance Convertible SqlValue Integer
instance Convertible Integer SqlValue
instance Convertible SqlValue Word64
instance Convertible Word64 SqlValue
instance Convertible SqlValue Word32
instance Convertible Word32 SqlValue
instance Convertible SqlValue Int64
instance Convertible Int64 SqlValue
instance Convertible SqlValue Int32
instance Convertible Int32 SqlValue
instance Convertible SqlValue Int
instance Convertible Int SqlValue
instance Convertible SqlValue ByteString
instance Convertible ByteString SqlValue
instance Convertible SqlValue ByteString
instance Convertible ByteString SqlValue
instance Convertible SqlValue String
instance Convertible String SqlValue
instance Eq SqlValue
instance Typeable SqlValue
-- | 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 Eq SqlInterval
instance Show SqlInterval
instance Read SqlInterval
instance Eq SqlTypeId
instance Show SqlTypeId
instance Read SqlTypeId
instance Eq SqlColDesc
instance Read SqlColDesc
instance Show SqlColDesc
instance Typeable SqlInterval
instance Typeable SqlTypeId
instance Typeable SqlColDesc
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 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.
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 he 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 Eq SqlError
instance Show SqlError
instance Read SqlError
instance Exception SqlError
instance Typeable SqlError
-- | Types for HDBC.
--
-- Please note: this module is intended for authors of database driver
-- libraries only. Authors of applications using HDBC should use
-- Database.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
disconnect :: (IConnection conn) => conn -> IO ()
commit :: (IConnection conn) => conn -> IO ()
rollback :: (IConnection conn) => conn -> IO ()
runRaw :: (IConnection conn) => conn -> String -> IO ()
run :: (IConnection conn) => conn -> String -> [SqlValue] -> IO Integer
prepare :: (IConnection conn) => conn -> String -> IO Statement
clone :: (IConnection conn) => conn -> IO conn
hdbcDriverName :: (IConnection conn) => conn -> String
hdbcClientVer :: (IConnection conn) => conn -> String
proxiedClientName :: (IConnection conn) => conn -> String
proxiedClientVer :: (IConnection conn) => conn -> String
dbServerVer :: (IConnection conn) => conn -> String
dbTransactionSupport :: (IConnection conn) => conn -> Bool
getTables :: (IConnection conn) => conn -> IO [String]
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 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.
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 he 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 :: ConnWrapper -> (forall conn. (IConnection conn) => conn -> b) -> b
instance IConnection 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
-- Database.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 he 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
disconnect :: (IConnection conn) => conn -> IO ()
commit :: (IConnection conn) => conn -> IO ()
rollback :: (IConnection conn) => conn -> IO ()
runRaw :: (IConnection conn) => conn -> String -> IO ()
run :: (IConnection conn) => conn -> String -> [SqlValue] -> IO Integer
prepare :: (IConnection conn) => conn -> String -> IO Statement
clone :: (IConnection conn) => conn -> IO conn
hdbcDriverName :: (IConnection conn) => conn -> String
hdbcClientVer :: (IConnection conn) => conn -> String
proxiedClientName :: (IConnection conn) => conn -> String
proxiedClientVer :: (IConnection conn) => conn -> String
dbServerVer :: (IConnection conn) => conn -> String
dbTransactionSupport :: (IConnection conn) => conn -> Bool
getTables :: (IConnection conn) => conn -> IO [String]
describeTable :: (IConnection conn) => conn -> String -> IO [(String, SqlColDesc)]
-- | 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 :: ConnWrapper -> (forall conn. (IConnection conn) => conn -> b) -> b
-- | Like run, but take a list of Maybe Strings instead of
-- SqlValues.
sRun :: (IConnection conn) => conn -> String -> [Maybe String] -> IO Integer
-- | 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]]
-- | 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 Database.HDBC.commit or Database.HDBC.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
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 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.
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