git.iko.soy/typeable/postgresql-simple
on master help sign in
Fix: allow empty hstore's and enfore complete parse.
96e4e1aSimon Meier
.ghcinew file+2
@@ -0,0 +1,2 @@
1+:set -isrc
2+:set Wall
postgresql-simple.cabal+1−1
@@ -1,5 +1,5 @@
1Name: postgresql-simple
1Name: postgresql-simple
2−Version: 0.3.1.0
2+Version: 0.3.1.1
3Synopsis: Mid-Level PostgreSQL client library
3Synopsis: Mid-Level PostgreSQL client library
4Description:
4Description:
5 Mid-Level PostgreSQL client library, forked from mysql-simple.
5 Mid-Level PostgreSQL client library, forked from mysql-simple.
src/Database/PostgreSQL/Simple/HStore/Implementation.hs+8−15
@@ -24,7 +24,6 @@ import qualified Data.Attoparsec.ByteString.Char8 as P (isSpace_w8)
24import qualified Data.ByteString as BS
24import qualified Data.ByteString as BS
25import Data.ByteString.Internal (c2w, w2c)
25import Data.ByteString.Internal (c2w, w2c)
26import qualified Data.ByteString.Lazy as BL
26import qualified Data.ByteString.Lazy as BL
27−import qualified Data.ByteString.Lazy.Internal as BL
28import Data.Map(Map)
27import Data.Map(Map)
29import qualified Data.Map as Map
28import qualified Data.Map as Map
30import Data.Text(Text)
29import Data.Text(Text)
@@ -129,7 +128,7 @@ instance FromField HStoreList where
129 else case mdat of
128 else case mdat of
130 Nothing -> returnError UnexpectedNull f ""
129 Nothing -> returnError UnexpectedNull f ""
131 Just dat ->
130 Just dat ->
132− case P.parseOnly parseHStore dat of
131+ case P.parseOnly (parseHStore <* P.endOfInput) dat of
133 Left err ->
132 Left err ->
134 returnError ConversionFailed f err
133 returnError ConversionFailed f err
135 Right (Left err) ->
134 Right (Left err) ->
@@ -152,19 +151,13 @@ instance FromField HStoreMap where
152 where convert (HStoreList xs) = HStoreMap (Map.fromList xs)
151 where convert (HStoreList xs) = HStoreMap (Map.fromList xs)
153
152
154parseHStore :: P.Parser (Either UnicodeException HStoreList)
153parseHStore :: P.Parser (Either UnicodeException HStoreList)
155−parseHStore = skipWhiteSpace >> loop id
154+parseHStore =
155+ reverseEither [] <$> P.sepBy' (skipWhiteSpace *> parseHStoreKeyVal)
156+ (skipWhiteSpace *> P.word8 (c2w ','))
156 where
157 where
157− loop acc = do
158+ reverseEither acc [] = Right (HStoreList acc)
158− mkv <- parseHStoreKeyVal
159+ reverseEither _acc ((Left err):_xs) = Left err
159− case mkv of
160+ reverseEither acc ((Right x ):xs) = reverseEither (x:acc) xs
160− Left err -> return (Left err)
161− Right kv -> do
162− skipWhiteSpace
163− (do
164− _ <- P.word8 (c2w ',')
165− skipWhiteSpace
166− loop (acc . (kv:))
167− ) <|> return (Right (HStoreList (acc [kv])))
168
161
169parseHStoreKeyVal :: P.Parser (Either UnicodeException (Text,Text))
162parseHStoreKeyVal :: P.Parser (Either UnicodeException (Text,Text))
170parseHStoreKeyVal = do
163parseHStoreKeyVal = do
@@ -199,7 +192,7 @@ parseHStoreTexts :: ([Text] -> [Text])
199parseHStoreTexts acc = do
192parseHStoreTexts acc = do
200 mchunk <- TS.decodeUtf8' <$> P.takeWhile (not . isSpecialChar)
193 mchunk <- TS.decodeUtf8' <$> P.takeWhile (not . isSpecialChar)
201 case mchunk of
194 case mchunk of
202− Left err -> return (Left err)
195+ Left err -> return (Left err)
203 Right chunk ->
196 Right chunk ->
204 (do
197 (do
205 _ <- P.word8 (c2w '\\')
198 _ <- P.word8 (c2w '\\')