sqlite-simple-errors-0.5.0.0: src/Database/SQLite/SimpleErrors/Parser.hs
{-|
Module : Database.SQLite.SimpleErrors.Parser
Description : Parsing logic
Copyright : (c) Joseph Canero, 2016
License : BSD-3
Maintainer : jmc41493@gmail.com
Stability : experimental
Portability : POSIX
-}
module Database.SQLite.SimpleErrors.Parser
(
receiveSQLError
)
where
import Control.Applicative ((<$>))
import Control.Monad
import Data.Text (Text)
import qualified Data.Text as Text hiding (Text)
import Database.SQLite.Simple
import Database.SQLite.SimpleErrors.Types
import Text.Parsec
import Text.Parsec.Text
type SQLiteParser = Parser SQLiteResponse
constraintNameOnly :: String -> Parser ()
constraintNameOnly n = void $ string (n ++ " constraint failed")
constraintName :: String -> Parser ()
constraintName n = constraintNameOnly n >> char ':' >> spaces
getRest :: Parser Text
getRest = Text.pack <$> many1 anyChar
parseConstraint :: String -> Constraint -> SQLiteParser
parseConstraint n c = constraintName n >> SQLConstraintError c <$> getRest
parseConstraintNoDetails :: String -> Constraint -> SQLiteParser
parseConstraintNoDetails n c =
constraintNameOnly n >> return (SQLConstraintError c Text.empty)
constraintParser :: Parsec Text () SQLiteResponse
constraintParser =
parseConstraintNoDetails "FOREIGN KEY" ForeignKey <|>
parseConstraint "NOT NULL" NotNull <|>
parseConstraint "UNIQUE" Unique <|>
parseConstraint "CHECK" Check
parseError :: SQLError -> SQLiteResponse
parseError e@SQLError{sqlErrorDetails = details} =
either (\_ -> SQLOtherError e) id $ parse constraintParser "" details
-- | Given a SQL error, converts it into a SQLiteResponse.
-- If the error is not an ErrorConstraint, it is essentially just wrapped in
-- SQLOtherError.
-- If the error is an ErrorConstraint error, try to parse the error as one
-- of the following kinds of constraint violations: Foreign Key, Not Null,
-- Unique, or Check.
receiveSQLError :: SQLError -> SQLiteResponse
receiveSQLError e@SQLError{sqlError = ErrorConstraint} = parseError e
receiveSQLError e = SQLOtherError e