simplest-sqlite 0.0.0.10 → 0.0.0.11
raw patch · 4 files changed
+271/−36 lines, 4 filesdep +exception-hierarchydep +template-haskell
Dependencies added: exception-hierarchy, template-haskell
Files
- simplest-sqlite.cabal +7/−4
- src/Database/SmplstSQLite3.hs +17/−27
- src/Database/SmplstSQLite3/Constants.hsc +199/−5
- src/Database/SmplstSQLite3/Templates.hs +48/−0
simplest-sqlite.cabal view
@@ -2,7 +2,7 @@ cabal-version: >= 1.8 name: simplest-sqlite-version: 0.0.0.10+version: 0.0.0.11 stability: Experimental author: YoshikuniJujo <PAF01143@nifty.ne.jp> maintainer: YoshikuniJujo <PAF01143@nifty.ne.jp>@@ -23,13 +23,16 @@ source-repository this type: git location: git://github.com/YoshikuniJujo/test_haskell- tag: simplest-sqlite-0.0.0.10+ tag: simplest-sqlite-0.0.0.11 library hs-source-dirs: src exposed-modules: Database.SmplstSQLite3- other-modules: Database.SmplstSQLite3.Constants- build-depends: base == 4.*, bytestring == 0.10.*, text >= 1.1 && < 1.3+ other-modules:+ Database.SmplstSQLite3.Constants, Database.SmplstSQLite3.Templates+ build-depends:+ base == 4.*, bytestring == 0.10.*, text >= 1.1 && < 1.3,+ exception-hierarchy == 0.0.0.1, template-haskell == 2.9.* ghc-options: -Wall extra-libraries: sqlite3 extensions: ForeignFunctionInterface
src/Database/SmplstSQLite3.hs view
@@ -5,7 +5,7 @@ withSQLite, withPrepared, step, reset, bind, SQLiteData(..), SQLiteDataList(..), columnType, -- * Types- SQLite, Stmt, Result(..), Type(..),+ SQLite, Stmt, Result(..), Type(..), SQLiteException(..), ) where import Control.Applicative@@ -18,6 +18,7 @@ import Foreign.C.Types import Foreign.C.String +import Database.SmplstSQLite3.Exception import Database.SmplstSQLite3.Constants data SQLite = SQLite (Ptr SQLite) deriving Show@@ -41,7 +42,7 @@ when (ret /= sQLITE_OK) $ do em <- sqlite3Errmsg sq sqlite3Close sq- ioError . userError $ "Cannot open database: " ++ em+ sqliteThrow ("Cannot open database: " ++ em) ret return sq sqlite3Close :: SQLite -> IO ()@@ -49,7 +50,7 @@ ret <- c_sqlite3_close db when (ret /= sQLITE_OK) $ do em <- sqlite3Errmsg sq- ioError . userError $ "Cannot close database: " ++ em+ sqliteThrow ("Cannot close database: " ++ em) ret sqlite3Errmsg :: SQLite -> IO String sqlite3Errmsg (SQLite db) = peekCString =<< c_sqlite3_errmsg db@@ -74,15 +75,13 @@ when (ret /= sQLITE_OK) $ do em <- sqlite3Errmsg db sqlite3Finalize sm- ioError . userError $ "Cannot prepare: " ++ em+ sqliteThrow ("Cannot prepare: " ++ em) ret (sm ,) <$> (peekCString =<< peek pt) sqlite3Finalize :: Stmt -> IO () sqlite3Finalize (Stmt psm) = do ret <- c_sqlite3_finalize psm- when (ret /= sQLITE_OK) $- ioError . userError $- "Cannot finalize stmt: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot finalize stmt" ret data Result = Busy | Row | Done deriving (Show, Eq) @@ -93,11 +92,9 @@ step (Stmt psm) = do ret <- c_sqlite3_step psm case ret of- _ | ret == sQLITE_BUSY -> return Busy- | ret == sQLITE_ROW -> return Row+ _ | ret == sQLITE_ROW -> return Row | ret == sQLITE_DONE -> return Done- _ -> ioError . userError $- "Error while step: error code (" ++ show ret ++ ")"+ _ -> sqliteThrow "Error while step" ret foreign import ccall unsafe "sqlite3.h sqlite3_column_int" c_sqlite3_column_int :: Ptr Stmt -> CInt -> IO CInt@@ -166,38 +163,32 @@ sqlite3BindNull :: Stmt -> Int -> () -> IO () sqlite3BindNull (Stmt sm) i _ = do ret <- c_sqlite3_bind_null sm (fromIntegral i)- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind null: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind null: error code" ret sqlite3BindDouble :: Stmt -> Int -> Double -> IO () sqlite3BindDouble (Stmt sm) i d = do ret <- c_sqlite3_bind_double sm (fromIntegral i) (realToFrac d)- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind double: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind double" ret sqlite3BindInt :: Stmt -> Int -> Int -> IO () sqlite3BindInt (Stmt sm) i n = do ret <- c_sqlite3_bind_int sm (fromIntegral i) (fromIntegral n)- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind int: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind int" ret sqlite3BindString :: Stmt -> Int -> String -> IO () sqlite3BindString (Stmt sm) i s = withCString s $ \cs -> do ret <- c_sqlite3_bind_text sm (fromIntegral i) cs (- 1) nullPtr- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind text: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind text" ret sqlite3BindByteString :: Stmt -> Int -> BS.ByteString -> IO () sqlite3BindByteString (Stmt sm) i s = BS.useAsCString s $ \cs -> do ret <- c_sqlite3_bind_text sm (fromIntegral i) cs (- 1) nullPtr- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind text: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind text" ret sqlite3BindBlob :: Stmt -> Int -> BS.ByteString -> IO () sqlite3BindBlob (Stmt sm) i s = BS.useAsCString s $ \cs -> do ret <- c_sqlite3_bind_blob sm (fromIntegral i) cs (- 1) nullPtr- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot bind text: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot bind text" ret foreign import ccall unsafe "sqlite3.h sqlite3_bind_parameter_index" c_sqlite3_bind_parameter_index ::@@ -206,8 +197,8 @@ sqlite3BindParameterIndex :: Stmt -> String -> IO Int sqlite3BindParameterIndex (Stmt sm) ph = withCString ph $ \cph -> do i <- c_sqlite3_bind_parameter_index sm cph- when (i == 0) . ioError . userError $- "no such place holder: `" ++ ph ++ "'"+ when (i == 0) .+ sqliteThrowBindError $ "no such place holder: `" ++ ph ++ "'" return $ fromIntegral i foreign import ccall unsafe "sqlite3.h sqlite3_reset" c_sqlite3_reset ::@@ -216,8 +207,7 @@ reset :: Stmt -> IO () reset (Stmt sm) = do ret <- c_sqlite3_reset sm- when (ret /= sQLITE_OK) . ioError . userError $- "Cannot reset stmt: error code (" ++ show ret ++ ")"+ when (ret /= sQLITE_OK) $ sqliteThrow "Cannot reset stmt" ret data Type = Integer | Float | Text | Blob | Null deriving (Show, Eq)
src/Database/SmplstSQLite3/Constants.hsc view
@@ -1,18 +1,212 @@ #include <sqlite3.h> module Database.SmplstSQLite3.Constants (- sQLITE_OK, sQLITE_ERROR, sQLITE_BUSY, sQLITE_ROW, sQLITE_DONE,- sQLITE_INTEGER, sQLITE_FLOAT, sQLITE_TEXT, sQLITE_BLOB, sQLITE_NULL+ sQLITE_INTEGER, sQLITE_FLOAT, sQLITE_TEXT, sQLITE_BLOB, sQLITE_NULL,++ sQLITE_OK, sQLITE_ROW, sQLITE_DONE,++ sQLITE_ERROR, sQLITE_INTERNAL, sQLITE_PERM,+ + sQLITE_ABORT_PLAIN, sQLITE_ABORT_ROLLBACK,++ sQLITE_BUSY_PLAIN, sQLITE_BUSY_RECOVERY, sQLITE_BUSY_SNAPSHOT,+ + sQLITE_LOCKED_PLAIN, sQLITE_LOCKED_SHAREDCACHE,+ + sQLITE_NOMEM,+ + sQLITE_READONLY_PLAIN, sQLITE_READONLY_RECOVERY,+ sQLITE_READONLY_CANTLOCK, sQLITE_READONLY_ROLLBACK,+ sQLITE_READONLY_DBMOVED,+ + sQLITE_INTERRUPT,++ sQLITE_IOERR_PLAIN, sQLITE_IOERR_READ, sQLITE_IOERR_SHORT_READ,+ sQLITE_IOERR_WRITE, sQLITE_IOERR_FSYNC, sQLITE_IOERR_DIR_FSYNC,+ sQLITE_IOERR_TRUNCATE, sQLITE_IOERR_FSTAT, sQLITE_IOERR_UNLOCK,+ sQLITE_IOERR_RDLOCK,+ sQLITE_IOERR_DELETE, sQLITE_IOERR_BLOCKED, sQLITE_IOERR_NOMEM,+ sQLITE_IOERR_ACCESS, sQLITE_IOERR_CHECKRESERVEDLOCK, sQLITE_IOERR_LOCK,+ sQLITE_IOERR_CLOSE, sQLITE_IOERR_DIR_CLOSE,+ sQLITE_IOERR_SHMOPEN, sQLITE_IOERR_SHMSIZE, sQLITE_IOERR_SHMLOCK,+ sQLITE_IOERR_SHMMAP,+ sQLITE_IOERR_SEEK, sQLITE_IOERR_DELETE_NOENT, sQLITE_IOERR_MMAP,+ sQLITE_IOERR_GETTEMPPATH, sQLITE_IOERR_CONVPATH,+ + sQLITE_CORRUPT_PLAIN, sQLITE_CORRUPT_VTAB,+ + sQLITE_NOTFOUND,+ sQLITE_FULL,+ + sQLITE_CANTOPEN_PLAIN, sQLITE_CANTOPEN_NOTEMPDIR, sQLITE_CANTOPEN_ISDIR,+ sQLITE_CANTOPEN_FULLPATH, sQLITE_CANTOPEN_CONVPATH,+ + sQLITE_PROTOCOL, sQLITE_EMPTY, sQLITE_SCHEMA, sQLITE_TOOBIG,+ + sQLITE_CONSTRAINT_PLAIN, sQLITE_CONSTRAINT_CHECK,+ sQLITE_CONSTRAINT_COMMITHOOK, sQLITE_CONSTRAINT_FOREIGNKEY,+ sQLITE_CONSTRAINT_FUNCTION, sQLITE_CONSTRAINT_NOTNULL,+ sQLITE_CONSTRAINT_PRIMARYKEY, sQLITE_CONSTRAINT_TRIGGER,+ sQLITE_CONSTRAINT_UNIQUE, sQLITE_CONSTRAINT_VTAB,+ sQLITE_CONSTRAINT_ROWID,+ + sQLITE_MISMATCH, sQLITE_MISUSE, sQLITE_NOLFS,+ + sQLITE_AUTH_PLAIN, sQLITE_AUTH_USER,+ + sQLITE_FORMAT, sQLITE_RANGE, sQLITE_NOTADB,+ + sQLITE_NOTICE_PLAIN, sQLITE_NOTICE_RECOVER_WAL,+ sQLITE_NOTICE_RECOVER_ROLLBACK,+ + sQLITE_WARNING_PLAIN, sQLITE_WARNING_AUTOINDEX ) where import Foreign.C.Types -sQLITE_OK, sQLITE_ERROR, sQLITE_BUSY, sQLITE_ROW, sQLITE_DONE :: CInt+sQLITE_OK, sQLITE_ROW, sQLITE_DONE :: CInt sQLITE_OK = #const SQLITE_OK-sQLITE_ERROR = #const SQLITE_ERROR-sQLITE_BUSY = #const SQLITE_BUSY sQLITE_ROW = #const SQLITE_ROW sQLITE_DONE = #const SQLITE_DONE++sQLITE_ERROR, sQLITE_INTERNAL, sQLITE_PERM :: CInt++sQLITE_ERROR = #const SQLITE_ERROR+sQLITE_INTERNAL = #const SQLITE_INTERNAL+sQLITE_PERM = #const SQLITE_PERM++sQLITE_ABORT_PLAIN, sQLITE_ABORT_ROLLBACK :: CInt+sQLITE_ABORT_PLAIN = #const SQLITE_ABORT+sQLITE_ABORT_ROLLBACK = #const SQLITE_ABORT_ROLLBACK++sQLITE_BUSY_PLAIN, sQLITE_BUSY_RECOVERY, sQLITE_BUSY_SNAPSHOT :: CInt+sQLITE_BUSY_PLAIN = #const SQLITE_BUSY+sQLITE_BUSY_RECOVERY = #const SQLITE_BUSY_RECOVERY+sQLITE_BUSY_SNAPSHOT = #const SQLITE_BUSY_SNAPSHOT+ +sQLITE_LOCKED_PLAIN, sQLITE_LOCKED_SHAREDCACHE :: CInt+sQLITE_LOCKED_PLAIN = #const SQLITE_LOCKED+sQLITE_LOCKED_SHAREDCACHE = #const SQLITE_LOCKED_SHAREDCACHE++sQLITE_NOMEM :: CInt+sQLITE_NOMEM = #const SQLITE_NOMEM++sQLITE_READONLY_PLAIN, sQLITE_READONLY_RECOVERY, sQLITE_READONLY_CANTLOCK,+ sQLITE_READONLY_ROLLBACK, sQLITE_READONLY_DBMOVED+ :: CInt+sQLITE_READONLY_PLAIN = #const SQLITE_READONLY+sQLITE_READONLY_RECOVERY = #const SQLITE_READONLY_RECOVERY+sQLITE_READONLY_CANTLOCK = #const SQLITE_READONLY_CANTLOCK+sQLITE_READONLY_ROLLBACK = #const SQLITE_READONLY_ROLLBACK+sQLITE_READONLY_DBMOVED = #const SQLITE_READONLY_DBMOVED++sQLITE_INTERRUPT :: CInt+sQLITE_INTERRUPT = #const SQLITE_INTERRUPT+ +sQLITE_IOERR_PLAIN, sQLITE_IOERR_READ, sQLITE_IOERR_SHORT_READ,+ sQLITE_IOERR_WRITE, sQLITE_IOERR_FSYNC, sQLITE_IOERR_DIR_FSYNC,+ sQLITE_IOERR_TRUNCATE, sQLITE_IOERR_FSTAT, sQLITE_IOERR_UNLOCK,+ sQLITE_IOERR_RDLOCK, sQLITE_IOERR_DELETE, sQLITE_IOERR_BLOCKED,+ sQLITE_IOERR_NOMEM, sQLITE_IOERR_ACCESS, sQLITE_IOERR_CHECKRESERVEDLOCK,+ sQLITE_IOERR_LOCK, sQLITE_IOERR_CLOSE, sQLITE_IOERR_DIR_CLOSE,+ sQLITE_IOERR_SHMOPEN, sQLITE_IOERR_SHMSIZE, sQLITE_IOERR_SHMLOCK,+ sQLITE_IOERR_SHMMAP, sQLITE_IOERR_SEEK, sQLITE_IOERR_DELETE_NOENT,+ sQLITE_IOERR_MMAP, sQLITE_IOERR_GETTEMPPATH, sQLITE_IOERR_CONVPATH+ :: CInt+sQLITE_IOERR_PLAIN = #const SQLITE_IOERR+sQLITE_IOERR_READ = #const SQLITE_IOERR_READ+sQLITE_IOERR_SHORT_READ = #const SQLITE_IOERR_SHORT_READ+sQLITE_IOERR_WRITE = #const SQLITE_IOERR_WRITE+sQLITE_IOERR_FSYNC = #const SQLITE_IOERR_FSYNC+sQLITE_IOERR_DIR_FSYNC = #const SQLITE_IOERR_DIR_FSYNC+sQLITE_IOERR_TRUNCATE = #const SQLITE_IOERR_TRUNCATE+sQLITE_IOERR_FSTAT = #const SQLITE_IOERR_FSTAT+sQLITE_IOERR_UNLOCK = #const SQLITE_IOERR_UNLOCK+sQLITE_IOERR_RDLOCK = #const SQLITE_IOERR_RDLOCK+sQLITE_IOERR_DELETE = #const SQLITE_IOERR_DELETE+sQLITE_IOERR_BLOCKED = #const SQLITE_IOERR_BLOCKED+sQLITE_IOERR_NOMEM = #const SQLITE_IOERR_NOMEM+sQLITE_IOERR_ACCESS = #const SQLITE_IOERR_ACCESS+sQLITE_IOERR_CHECKRESERVEDLOCK = #const SQLITE_IOERR_CHECKRESERVEDLOCK+sQLITE_IOERR_LOCK = #const SQLITE_IOERR_LOCK+sQLITE_IOERR_CLOSE = #const SQLITE_IOERR_CLOSE+sQLITE_IOERR_DIR_CLOSE = #const SQLITE_IOERR_DIR_CLOSE+sQLITE_IOERR_SHMOPEN = #const SQLITE_IOERR_SHMOPEN+sQLITE_IOERR_SHMSIZE = #const SQLITE_IOERR_SHMSIZE+sQLITE_IOERR_SHMLOCK = #const SQLITE_IOERR_SHMLOCK+sQLITE_IOERR_SHMMAP = #const SQLITE_IOERR_SHMMAP+sQLITE_IOERR_SEEK = #const SQLITE_IOERR_SEEK+sQLITE_IOERR_DELETE_NOENT = #const SQLITE_IOERR_DELETE_NOENT+sQLITE_IOERR_MMAP = #const SQLITE_IOERR_MMAP+sQLITE_IOERR_GETTEMPPATH = #const SQLITE_IOERR_GETTEMPPATH+sQLITE_IOERR_CONVPATH = #const SQLITE_IOERR_CONVPATH+-- sQLITE_IOERR_VNODE = #const SQLITE_IOERR_VNODE++sQLITE_CORRUPT_PLAIN, sQLITE_CORRUPT_VTAB :: CInt+sQLITE_CORRUPT_PLAIN = #const SQLITE_CORRUPT+sQLITE_CORRUPT_VTAB = #const SQLITE_CORRUPT_VTAB++sQLITE_NOTFOUND, sQLITE_FULL :: CInt+sQLITE_NOTFOUND = #const SQLITE_NOTFOUND+sQLITE_FULL = #const SQLITE_FULL+ +sQLITE_CANTOPEN_PLAIN, sQLITE_CANTOPEN_NOTEMPDIR, sQLITE_CANTOPEN_ISDIR,+ sQLITE_CANTOPEN_FULLPATH, sQLITE_CANTOPEN_CONVPATH+ :: CInt+sQLITE_CANTOPEN_PLAIN = #const SQLITE_CANTOPEN+sQLITE_CANTOPEN_NOTEMPDIR = #const SQLITE_CANTOPEN_NOTEMPDIR+sQLITE_CANTOPEN_ISDIR = #const SQLITE_CANTOPEN_ISDIR+sQLITE_CANTOPEN_FULLPATH = #const SQLITE_CANTOPEN_FULLPATH+sQLITE_CANTOPEN_CONVPATH = #const SQLITE_CANTOPEN_CONVPATH+ +sQLITE_PROTOCOL, sQLITE_EMPTY, sQLITE_SCHEMA, sQLITE_TOOBIG :: CInt+sQLITE_PROTOCOL = #const SQLITE_PROTOCOL+sQLITE_EMPTY = #const SQLITE_EMPTY+sQLITE_SCHEMA = #const SQLITE_SCHEMA+sQLITE_TOOBIG = #const SQLITE_TOOBIG++sQLITE_CONSTRAINT_PLAIN, sQLITE_CONSTRAINT_CHECK,+ sQLITE_CONSTRAINT_COMMITHOOK, sQLITE_CONSTRAINT_FOREIGNKEY,+ sQLITE_CONSTRAINT_FUNCTION, sQLITE_CONSTRAINT_NOTNULL,+ sQLITE_CONSTRAINT_PRIMARYKEY, sQLITE_CONSTRAINT_TRIGGER,+ sQLITE_CONSTRAINT_UNIQUE, sQLITE_CONSTRAINT_VTAB,+ sQLITE_CONSTRAINT_ROWID+ :: CInt+sQLITE_CONSTRAINT_PLAIN = #const SQLITE_CONSTRAINT+sQLITE_CONSTRAINT_CHECK = #const SQLITE_CONSTRAINT_CHECK+sQLITE_CONSTRAINT_COMMITHOOK = #const SQLITE_CONSTRAINT_COMMITHOOK+sQLITE_CONSTRAINT_FOREIGNKEY = #const SQLITE_CONSTRAINT_FOREIGNKEY+sQLITE_CONSTRAINT_FUNCTION = #const SQLITE_CONSTRAINT_FUNCTION+sQLITE_CONSTRAINT_NOTNULL = #const SQLITE_CONSTRAINT_NOTNULL+sQLITE_CONSTRAINT_PRIMARYKEY = #const SQLITE_CONSTRAINT_PRIMARYKEY+sQLITE_CONSTRAINT_TRIGGER = #const SQLITE_CONSTRAINT_TRIGGER+sQLITE_CONSTRAINT_UNIQUE = #const SQLITE_CONSTRAINT_UNIQUE+sQLITE_CONSTRAINT_VTAB = #const SQLITE_CONSTRAINT_VTAB+sQLITE_CONSTRAINT_ROWID = #const SQLITE_CONSTRAINT_ROWID++sQLITE_MISMATCH, sQLITE_MISUSE, sQLITE_NOLFS :: CInt+sQLITE_MISMATCH = #const SQLITE_MISMATCH+sQLITE_MISUSE = #const SQLITE_MISUSE+sQLITE_NOLFS = #const SQLITE_NOLFS++sQLITE_AUTH_PLAIN, sQLITE_AUTH_USER :: CInt+sQLITE_AUTH_PLAIN = #const SQLITE_AUTH+sQLITE_AUTH_USER = #const SQLITE_AUTH_USER++sQLITE_FORMAT, sQLITE_RANGE, sQLITE_NOTADB :: CInt+sQLITE_FORMAT = #const SQLITE_FORMAT+sQLITE_RANGE = #const SQLITE_RANGE+sQLITE_NOTADB = #const SQLITE_NOTADB++sQLITE_NOTICE_PLAIN, sQLITE_NOTICE_RECOVER_WAL, sQLITE_NOTICE_RECOVER_ROLLBACK+ :: CInt+sQLITE_NOTICE_PLAIN = #const SQLITE_NOTICE+sQLITE_NOTICE_RECOVER_WAL = #const SQLITE_NOTICE_RECOVER_WAL+sQLITE_NOTICE_RECOVER_ROLLBACK = #const SQLITE_NOTICE_RECOVER_ROLLBACK++sQLITE_WARNING_PLAIN, sQLITE_WARNING_AUTOINDEX :: CInt+sQLITE_WARNING_PLAIN = #const SQLITE_WARNING+sQLITE_WARNING_AUTOINDEX = #const SQLITE_WARNING_AUTOINDEX sQLITE_INTEGER, sQLITE_FLOAT, sQLITE_TEXT, sQLITE_BLOB, sQLITE_NULL :: CInt sQLITE_INTEGER = #const SQLITE_INTEGER
+ src/Database/SmplstSQLite3/Templates.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE TemplateHaskell #-}++module Database.SmplstSQLite3.Templates (newException, mkSqliteThrow) where++import Control.Applicative+import Control.Exception+import Data.Typeable+import Data.Char+import Language.Haskell.TH+import Foreign.C.Types++newException :: String -> DecQ+newException e =+ newtypeD (cxt []) (mkName e) []+ (normalC (mkName e) [strictType notStrict (conT ''String)])+ [''Typeable, ''Show]++sqliteThrowType :: DecQ+sqliteThrowType = sigD (mkName "sqliteThrow") .+ forallT [PlainTV $ mkName "a"] (cxt []) $+ conT ''String `arrT` conT ''CInt `arrT`+ (conT ''IO `appT` varT (mkName "a"))++mkSqliteThrow :: [Name] -> DecsQ+mkSqliteThrow nms = (:)+ <$> sqliteThrowType+ <*> ((: []) <$> funD (mkName "sqliteThrow") [mc nms])+ where+ mc ns = clause [varP $ mkName "em", varP $ mkName "rc"]+ (guardedB $+ map gd1 ns ++ [(,) <$> normalG otgd <*> otbd])+ []+ gd1 n = (,) <$> normalG (gd $ nameBase n) <*> bd n+ gd n = infixE (Just . varE $ mkName "rc") (varE '(==))+ (Just . varE . mkName $ toLowerH n)+ bd n = infixE (Just $ varE 'throwIO) (varE '($)) . Just $+ conE n `appE` varE (mkName "em")+ otgd = varE 'otherwise+ otbd = infixE (Just $ varE 'throwIO) (varE '($)) . Just $+ conE (mkName "SQLITE_ERROR_OTHER") `appE` varE (mkName "rc") `appE` varE (mkName "em")++toLowerH :: String -> String+toLowerH (c : cs) = toLower c : cs+toLowerH _ = ""++infixr `arrT`+arrT :: TypeQ -> TypeQ -> TypeQ+arrT t1 t2 = arrowT `appT` t1 `appT` t2