1{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
2------------------------------------------------------------------------------
3-- |
4-- Module:      Database.SQLite.Simple.Internal
5-- Copyright:   (c) 2011-2012 Leon P Smith
6--              (c) 2012-2013 Janne Hellsten
7-- License:     BSD3
8-- Maintainer:  Janne Hellsten <jjhellst@gmail.com>
9-- Portability: portable
10--
11-- Internal bits.  This interface is less stable and can change at any time.
12-- In particular this means that while the rest of the sqlite-simple
13-- package endeavors to follow the package versioning policy,  this module
14-- does not.  Also, at the moment there are things in here that aren't
15-- particularly internal and are exported elsewhere;  these will eventually
16-- disappear from this module.
17--
18------------------------------------------------------------------------------
19
20module Database.SQLite.Simple.Internal where
21
22import           Control.Exception (Exception)
23import           Control.Monad
24import           Control.Applicative
25import           Data.ByteString (ByteString)
26import           Data.ByteString.Char8()
27import           Data.Typeable (Typeable)
28import           Control.Monad.Trans.State.Strict
29import           Control.Monad.Trans.Reader
30
31import           Database.SQLite.Simple.Ok
32import qualified Database.SQLite3 as Base
33
34-- | Connection to an open database.
35--
36-- You can use 'connectionHandle' to gain access to the underlying
37-- <http://hackage.haskell.org/package/direct-sqlite> connection.
38-- This may be useful if you need to access some direct-sqlite
39-- functionality that's not exposed in the sqlite-simple API.  This
40-- should be a safe thing to do although mixing both APIs is
41-- discouraged.
42newtype Connection = Connection { connectionHandle :: Base.Database }
43
44data ColumnOutOfBounds = ColumnOutOfBounds { errorColumnIndex :: !Int }
45                      deriving (Eq, Show, Typeable)
46
47instance Exception ColumnOutOfBounds
48
49-- | A Field represents metadata about a particular field
50data Field = Field {
51     result   :: Base.SQLData
52   , column   :: {-# UNPACK #-} !Int
53   }
54
55-- Named type for holding RowParser read-only state.  Just for making
56-- it easier to make sense out of types in FromRow.
57newtype RowParseRO = RowParseRO { nColumns :: Int }
58
59newtype RowParser a = RP { unRP :: ReaderT RowParseRO (StateT (Int, [Base.SQLData]) Ok) a }
60   deriving ( Functor, Applicative, Alternative, Monad, MonadPlus )
61
62gettypename :: Base.SQLData -> ByteString
63gettypename (Base.SQLInteger _) = "INTEGER"
64gettypename (Base.SQLFloat _) = "FLOAT"
65gettypename (Base.SQLText _) = "TEXT"
66gettypename (Base.SQLBlob _) = "BLOB"
67gettypename Base.SQLNull = "NULL"
68
69