-- 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.2 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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: -- -- -- -- 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