module Database.HDBC.PostgreSQL.HStore where
import Database.HDBC
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8)
import qualified Data.Text as T
import qualified Data.Attoparsec.Text as AP
import qualified Data.List as L
import qualified Data.Map as M
hsQuery :: [(String, String)] -> String
hsQuery = L.intercalate " || " . map (\(_, _) -> "hstore(?, ?)")
hsParams :: [(String, String)] -> [SqlValue]
hsParams = L.concatMap (\(k, v) -> [toSql k, toSql v])
hsParse :: SqlValue -> M.Map Text Text
hsParse (SqlByteString bs) = case hstoreParser `AP.parseOnly` decodeUtf8 bs of
Left err -> error err
Right val -> val
hstoreParser :: AP.Parser (M.Map Text Text)
hstoreParser = do
pairs <- kvPair `AP.sepBy` AP.string (T.pack ", ")
return $! M.fromList pairs
kvPair :: AP.Parser (Text, Text)
kvPair = do
key <- doubleQuoted
AP.string $ T.pack "=>"
value <- doubleQuoted
return (key, value)
doubleQuoted :: AP.Parser Text
doubleQuoted = do
AP.char '"'
str <- AP.scan False $ \s c -> if s then Just False
else if c == '"'
then Nothing
else Just (c == '\\')
AP.char '"'
return $! T.replace (T.pack "\\\"") (T.singleton '"') str