postgresql-simple 0.3.6.0 → 0.3.7.0
raw patch · 9 files changed
+114/−39 lines, 9 filesdep +aesondep ~bytestring
Dependencies added: aeson
Dependency ranges changed: bytestring
Files
- postgresql-simple.cabal +4/−3
- src/Database/PostgreSQL/Simple/Copy.hs +4/−4
- src/Database/PostgreSQL/Simple/Errors.hs +31/−3
- src/Database/PostgreSQL/Simple/FromField.hs +47/−7
- src/Database/PostgreSQL/Simple/FromRow.hs +3/−2
- src/Database/PostgreSQL/Simple/Internal.hs +7/−0
- src/Database/PostgreSQL/Simple/ToField.hs +14/−0
- src/Database/PostgreSQL/Simple/Transaction.hs +1/−17
- src/Database/PostgreSQL/Simple/TypeInfo/Macro.hs +3/−3
postgresql-simple.cabal view
@@ -1,5 +1,5 @@ Name: postgresql-simple-Version: 0.3.6.0+Version: 0.3.7.0 Synopsis: Mid-Level PostgreSQL client library Description: Mid-Level PostgreSQL client library, forked from mysql-simple.@@ -52,11 +52,12 @@ Database.PostgreSQL.Simple.TypeInfo.Types Build-depends:+ aeson >= 0.6, attoparsec >= 0.10.3, base < 5, blaze-builder, blaze-textual,- bytestring >= 0.9,+ bytestring >= 0.10, containers, postgresql-libpq >= 0.6.2, template-haskell,@@ -77,7 +78,7 @@ source-repository this type: git location: http://github.com/lpsmith/postgresql-simple- tag: v0.3.6.0+ tag: v0.3.7.0 test-suite test type: exitcode-stdio-1.0
src/Database/PostgreSQL/Simple/Copy.hs view
@@ -53,7 +53,7 @@ -- | Issue a @COPY FROM STDIN@ or @COPY TO STDOUT@ query. In the former -- case, the connection's state will change to @CopyIn@; in the latter,--- @CopyOut@. The connection must be in the normal state in order+-- @CopyOut@. The connection must be in the ready state in order -- to call this function. Performs parameter subsitution. copy :: ( ToRow params ) => Connection -> Query -> params -> IO ()@@ -64,7 +64,7 @@ -- | Issue a @COPY FROM STDIN@ or @COPY TO STDOUT@ query. In the former -- case, the connection's state will change to @CopyIn@; in the latter,--- @CopyOut@. The connection must be in the normal state in order+-- @CopyOut@. The connection must be in the ready state in order -- to call this function. Does not perform parameter subsitution. copy_ :: Connection -> Query -> IO ()@@ -163,7 +163,7 @@ -- -- A connection must be in the @CopyIn@ state in order to call this -- function, otherwise a 'SqlError' exception will result. The--- connection's state changes back to normal after this function+-- connection's state changes back to ready after this function -- is called. putCopyEnd :: Connection -> IO Int64@@ -180,7 +180,7 @@ -- -- A connection must be in the @CopyIn@ state in order to call this -- function, otherwise a 'SqlError' exception will result. The--- connection's state changes back to normal after this function+-- connection's state changes back to ready after this function -- is called. putCopyError :: Connection -> B.ByteString -> IO ()
src/Database/PostgreSQL/Simple/Errors.hs view
@@ -1,9 +1,17 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-}---- | Module for parsing errors from posgresql error messages.--- Currently in only parses integrity violation errors (class 23).+{-# LANGUAGE RecordWildCards #-}+------------------------------------------------------------------------------+-- |+-- Module: Database.PostgreSQL.Simple.Errors+-- Copyright: (c) 2012-2013 Leonid Onokhov, Joey Adams+-- License: BSD3+-- Maintainer: Leon P Smith <leon@melding-monads.com>+-- Stability: experimental --+-- | Module for parsing errors from postgresql error messages.+-- Currently only parses integrity violation errors (class 23).+-- -- /Note: Success of parsing may depend on language settings./ ---------------------------------------------------------- module Database.PostgreSQL.Simple.Errors@@ -11,6 +19,9 @@ , constraintViolation , constraintViolationE , catchViolation+ , isSerializationError+ , isNoActiveTransactionError+ , isFailedTransactionError ) where @@ -106,3 +117,20 @@ parseMaybe :: Parser a -> ByteString -> Maybe a parseMaybe p b = either (const Nothing) Just $ parseOnly p b++------------------------------------------------------------------------+-- Error predicates+--+-- http://www.postgresql.org/docs/current/static/errcodes-appendix.html++isSerializationError :: SqlError -> Bool+isSerializationError = isSqlState "40001"++isNoActiveTransactionError :: SqlError -> Bool+isNoActiveTransactionError = isSqlState "25P01"++isFailedTransactionError :: SqlError -> Bool+isFailedTransactionError = isSqlState "25P02"++isSqlState :: ByteString -> SqlError -> Bool+isSqlState s SqlError{..} = sqlState == s
src/Database/PostgreSQL/Simple/FromField.hs view
@@ -87,6 +87,8 @@ , typeOid , PQ.Oid(..) , PQ.Format(..)++ , fromJSONField ) where #include "MachDeps.h"@@ -94,6 +96,7 @@ import Control.Applicative ( Applicative, (<|>), (<$>), pure ) import Control.Exception (Exception)+import qualified Data.Aeson as JSON import Data.Attoparsec.Char8 hiding (Result) import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as B@@ -162,14 +165,16 @@ -- library instances, this will usually be a single 'ResultError', but -- may be a 'UnicodeException'. --- -- Implementations of 'fromField' should not retain any references to- -- the 'Field' nor the 'ByteString' arguments after the result has- -- been evaluated to WHNF. Such a reference causes the entire- -- @LibPQ.'PQ.Result'@ to be retained.+ -- Note that retaining any reference to the 'Field' or 'ByteString'+ -- arguments causes the entire @LibPQ.'PQ.Result'@ to be retained.+ -- Thus, as a rule of thumb, implementations of 'fromField' should+ -- not refer to these values after the result has been evaluated+ -- to WHNF. But it can be profitable to break this rule when you+ -- know it won't cause memory management problems. --- -- For example, the instance for 'ByteString' uses 'B.copy' to avoid- -- such a reference, and that using bytestring functions such as 'B.drop'- -- and 'B.takeWhile' alone will also trigger this memory leak.+ -- The instances included with postgresql-simple follow this rule+ -- of thumb (modulo bugs). For example, the instance for 'ByteString'+ -- uses 'B.copy' to avoid such a reference. -- | Returns the data type name. This is the preferred way of identifying -- types that do not have a stable type oid, such as types provided by@@ -226,6 +231,12 @@ format :: Field -> PQ.Format format Field{..} = unsafeDupablePerformIO (PQ.fformat result column) +-- | void+instance FromField () where+ fromField f _bs+ | typeOid f /= $(inlineTypoid TI.void) = returnError Incompatible f ""+ | otherwise = pure ()+ -- | For dealing with null values. Compatible with any postgresql type -- compatible with type @a@. Note that the type is not checked if -- the value is null, although it is inadvisable to rely on this@@ -432,6 +443,35 @@ parseIt item = (fromField f' . Just . fmt delim) item where f' | Arrays.Array _ <- item = f | otherwise = fElem++-- | json+instance FromField JSON.Value where+ fromField f mbs =+ if typeOid f /= $(inlineTypoid TI.json)+ then returnError Incompatible f ""+ else case mbs of+ Nothing -> returnError UnexpectedNull f ""+ Just bs ->+ case JSON.eitherDecode' $ LB.fromStrict bs of+ Left err -> returnError ConversionFailed f err+ Right val -> pure val++-- | Parse a field to a JSON 'JSON.Value' and convert that into a+-- Haskell value using 'JSON.fromJSON'.+--+-- This can be used as the default implementation for the 'fromField'+-- method for Haskell types that have a JSON representation in+-- PostgreSQL.+--+-- The 'Typeable' constraint is required to show more informative+-- error messages when parsing fails.+fromJSONField :: (JSON.FromJSON a, Typeable a) => FieldParser a+fromJSONField f mbBs = do+ value <- fromField f mbBs+ case JSON.fromJSON value of+ JSON.Error err -> returnError ConversionFailed f $+ "JSON decoding error: " ++ err+ JSON.Success x -> pure x type Compat = PQ.Oid -> Bool
src/Database/PostgreSQL/Simple/FromRow.hs view
@@ -59,8 +59,9 @@ -- exception will be thrown. -- -- Note that 'field' evaluates it's result to WHNF, so the caveats listed in--- previous versions of postgresql-simple no longer apply. Instead, look--- at the caveats associated with user-defined implementations of 'fromRow'.+-- mysql-simple and very early versions of postgresql-simple no longer apply.+-- Instead, look at the caveats associated with user-defined implementations+-- of 'fromField'. class FromRow a where fromRow :: RowParser a
src/Database/PostgreSQL/Simple/Internal.hs view
@@ -44,6 +44,7 @@ import Database.PostgreSQL.Simple.TypeInfo.Types(TypeInfo) import Control.Monad.Trans.State.Strict import Control.Monad.Trans.Reader+import Control.Monad.Trans.Class import GHC.IO.Exception -- | A Field represents metadata about a particular field@@ -296,7 +297,13 @@ newtype RowParser a = RP { unRP :: ReaderT Row (StateT PQ.Column Conversion) a } deriving ( Functor, Applicative, Alternative, Monad ) +liftRowParser :: IO a -> RowParser a+liftRowParser = RP . lift . lift . liftConversion+ newtype Conversion a = Conversion { runConversion :: Connection -> IO (Ok a) }++liftConversion :: IO a -> Conversion a+liftConversion m = Conversion (\_ -> Ok <$> m) instance Functor Conversion where fmap f m = Conversion $ \conn -> (fmap . fmap) f (runConversion m conn)
src/Database/PostgreSQL/Simple/ToField.hs view
@@ -18,12 +18,14 @@ ( Action(..) , ToField(..)+ , toJSONField , inQuotes ) where import Blaze.ByteString.Builder (Builder, fromByteString, toByteString) import Blaze.ByteString.Builder.Char8 (fromChar) import Blaze.Text (integral, double, float)+import qualified Data.Aeson as JSON import Data.ByteString (ByteString) import Data.Int (Int8, Int16, Int32, Int64) import Data.List (intersperse)@@ -229,6 +231,18 @@ [Plain (fromChar ']')] -- Because the ARRAY[...] input syntax is being used, it is possible -- that the use of type-specific separator characters is unnecessary.++instance ToField JSON.Value where+ toField = toField . JSON.encode++-- | Convert a Haskell value to a JSON 'JSON.Value' using+-- 'JSON.toJSON' and convert that to a field using 'toField'.+--+-- This can be used as the default implementation for the 'toField'+-- method for Haskell types that have a JSON representation in+-- PostgreSQL.+toJSONField :: JSON.ToJSON a => a -> Action+toJSONField = toField . JSON.toJSON -- | Surround a string with single-quote characters: \"@'@\" --
src/Database/PostgreSQL/Simple/Transaction.hs view
@@ -40,6 +40,7 @@ import qualified Data.ByteString as B import Database.PostgreSQL.Simple.Internal import Database.PostgreSQL.Simple.Types+import Database.PostgreSQL.Simple.Errors import Database.PostgreSQL.Simple.Compat (mask, (<>)) @@ -244,20 +245,3 @@ execute_ conn sql >> return () where sql = "ROLLBACK TO SAVEPOINT " <> name <> "; RELEASE SAVEPOINT " <> name----------------------------------------------------------------------------- Error predicates------ http://www.postgresql.org/docs/current/static/errcodes-appendix.html--isSerializationError :: SqlError -> Bool-isSerializationError = isSqlState "40001"--isNoActiveTransactionError :: SqlError -> Bool-isNoActiveTransactionError = isSqlState "25P01"--isFailedTransactionError :: SqlError -> Bool-isFailedTransactionError = isSqlState "25P02"--isSqlState :: ByteString -> SqlError -> Bool-isSqlState s SqlError{..} = sqlState == s
src/Database/PostgreSQL/Simple/TypeInfo/Macro.hs view
@@ -34,9 +34,9 @@ catchAll :: MatchQ catchAll = match wildP (normalB [| False |]) [] --- | Literally substitute the value of a TypeInfo expression. Returns--- an expression of type 'Oid'. Useful because GHC tends not to--- fold constants.+-- | Literally substitute the 'typoid' of a 'TypeInfo' expression.+-- Returns an expression of type 'Oid'. Useful because GHC tends+-- not to fold constants. inlineTypoid :: TypeInfo -> ExpQ inlineTypoid ty = [| Oid $(litE (getTypoid ty)) |]