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