-- #hide module Database.HSQL.Types where import Control.Concurrent.MVar import Control.Exception import Data.Dynamic import Foreign import Foreign.C type FieldDef = (String, SqlType, Bool) data SqlType = SqlChar Int -- ODBC, MySQL, PostgreSQL | SqlVarChar Int -- ODBC, MySQL, PostgreSQL, MSI | SqlLongVarChar Int -- ODBC | SqlText -- , , PostgreSQL, MSI | SqlWChar Int -- ODBC | SqlWVarChar Int -- ODBC | SqlWLongVarChar Int -- ODBC | SqlDecimal Int Int -- ODBC | SqlNumeric Int Int -- ODBC, MySQL, PostgreSQL | SqlSmallInt -- ODBC, MySQL, PostgreSQL | SqlMedInt -- , MySQL, | SqlInteger -- ODBC, MySQL, PostgreSQL, MSI | SqlReal -- ODBC, MySQL, PostgreSQL | SqlFloat -- ODBC | SqlDouble -- ODBC, MySQL, PostgreSQL | SqlBit -- ODBC, , PostgreSQL | SqlTinyInt -- ODBC, MySQL, PostgreSQL | SqlBigInt -- ODBC, MySQL, PostgreSQL, MSI | SqlBinary Int -- ODBC, , PostgreSQL | SqlVarBinary Int -- ODBC, , PostgreSQL | SqlLongVarBinary Int -- ODBC | SqlDate -- ODBC, MySQL, PostgreSQL | SqlTime -- ODBC, MySQL, PostgreSQL | SqlTimeTZ -- , , PostgreSQL | SqlAbsTime -- , , PostgreSQL | SqlRelTime -- , , PostgreSQL | SqlTimeInterval -- , , PostgreSQL | SqlAbsTimeInterval -- , , PostgreSQL | SqlTimeStamp -- ODBC, MySQL | SqlDateTime -- , MySQL | SqlDateTimeTZ -- , MySQL, PostgreSQL | SqlYear -- , MySQL | SqlSET -- , MySQL | SqlENUM -- , MySQL | SqlBLOB -- , MySQL, , MSI | SqlMoney -- , , PostgreSQL | SqlINetAddr -- , , PostgreSQL | SqlCIDRAddr -- , , PostgreSQL | SqlMacAddr -- , , PostgreSQL | SqlPoint -- , , PostgreSQL | SqlLSeg -- , , PostgreSQL | SqlPath -- , , PostgreSQL | SqlBox -- , , PostgreSQL | SqlPolygon -- , , PostgreSQL | SqlLine -- , , PostgreSQL | SqlCircle -- , , PostgreSQL | SqlUnknown Int -- ^ HSQL returns @SqlUnknown tp@ for all -- columns for which it cannot determine -- the right type. The @tp@ here is the -- internal type code returned from the -- backend library deriving (Eq, Show) data SqlError = SqlError { seState :: String , seNativeError :: Int , seErrorMsg :: String } | SqlNoData | SqlInvalidHandle | SqlStillExecuting | SqlNeedData | SqlBadTypeCast { seFieldName :: String , seFieldType :: SqlType } | SqlFetchNull { seFieldName :: String } | SqlUnknownField { seFieldName :: String } | SqlUnsupportedOperation | SqlClosedHandle #ifdef __GLASGOW_HASKELL__ deriving Typeable #endif sqlErrorTc :: TyCon sqlErrorTc = mkTyCon "Database.HSQL.SqlError" #ifndef __GLASGOW_HASKELL__ instance Typeable SqlError where typeOf _ = mkAppTy sqlErrorTc [] #endif instance Show SqlError where showsPrec _ (SqlError{seErrorMsg=msg}) = showString msg showsPrec _ SqlNoData = showString "No data" showsPrec _ SqlInvalidHandle = showString "Invalid handle" showsPrec _ SqlStillExecuting = showString "Stlll executing" showsPrec _ SqlNeedData = showString "Need data" showsPrec _ (SqlBadTypeCast name tp) = showString ("The type of " ++ name ++ " field can't be converted to " ++ show tp ++ " type") showsPrec _ (SqlFetchNull name) = showString ("The value of " ++ name ++ " field is null") showsPrec _ (SqlUnknownField name) = showString ("Unknown field name: " ++ name) showsPrec _ SqlUnsupportedOperation = showString "Unsupported operation" showsPrec _ SqlClosedHandle = showString "The referenced handle is already closed" -- | A 'Connection' type represents a connection to a database, through which you can operate on the it. -- In order to create the connection you need to use the @connect@ function from the module for -- your prefered backend. data Connection = Connection { connDisconnect :: IO () , connExecute :: String -> IO () , connQuery :: String -> IO Statement , connTables :: IO [String] , connDescribe :: String -> IO [FieldDef] , connBeginTransaction :: IO () , connCommitTransaction :: IO () , connRollbackTransaction :: IO () , connClosed :: MVar Bool } -- | The 'Statement' type represents a result from the execution of given SQL query. data Statement = Statement { stmtConn :: Connection , stmtClose :: IO () , stmtFetch :: IO Bool , stmtGetCol :: forall a . Int -> FieldDef -> (FieldDef -> CString -> Int -> IO a) -> IO a , stmtFields :: [FieldDef] , stmtClosed :: MVar Bool } class SqlBind a where -- This allows for faster conversion for eq. integral numeric types, etc. -- Default version uses fromSqlValue. fromSqlCStringLen :: FieldDef -> CString -> Int -> IO a fromSqlCStringLen (name,sqlType,_) cstr cstrLen | cstr == nullPtr = throwDyn (SqlFetchNull name) | otherwise = do str <- peekCStringLen (cstr, cstrLen) case fromSqlValue sqlType str of Nothing -> throwDyn (SqlBadTypeCast name sqlType) Just v -> return v fromSqlValue :: SqlType -> String -> Maybe a toSqlValue :: a -> String