packages feed

postgresql-simple 0.4.2.0 → 0.4.2.1

raw patch · 6 files changed

+103/−31 lines, 6 files

Files

postgresql-simple.cabal view
@@ -1,5 +1,5 @@ Name:                postgresql-simple-Version:             0.4.2.0+Version:             0.4.2.1 Synopsis:            Mid-Level PostgreSQL client library Description:     Mid-Level PostgreSQL client library, forked from mysql-simple.@@ -81,7 +81,7 @@ source-repository this   type:     git   location: http://github.com/lpsmith/postgresql-simple-  tag:      v0.4.1.0+  tag:      v0.4.2.1  test-suite test   type:           exitcode-stdio-1.0
src/Database/PostgreSQL/Simple.hs view
@@ -343,6 +343,27 @@ -- Returns the number of rows affected. -- -- Throws 'FormatError' if the query could not be formatted correctly.+--+-- For example,  here's a command that inserts two rows into a table+-- with two columns:+--+-- @+-- executeMany c [sql|+--     INSERT INTO sometable VALUES (?,?)+--  |] [(1, \"hello\"),(2, \"world\")]+-- @+--+-- Here's an canonical example of a multi-row update command:+--+-- @+-- executeMany c [sql|+--     UPDATE sometable+--        SET sometable.y = upd.y+--       FROM (VALUES (?,?)) as upd(x,y)+--      WHERE sometable.x = upd.x+--  |] [(1, \"hello\"),(2, \"world\")+-- @+ executeMany :: (ToRow q) => Connection -> Query -> [q] -> IO Int64 executeMany _ _ [] = return 0 executeMany conn q qs = do
src/Database/PostgreSQL/Simple/FromField.hs view
@@ -23,6 +23,14 @@ since a 'Double' might lose precision if representing PostgreSQL's 64-bit @bigint@, the two are /not/ considered compatible. +Note that the 'Float' and 'Double' instances use attoparsec's 'double'+conversion routine,  which sacrifices some accuracy for speed.   If you+need accuracy,  consider first converting data to a 'Scientific' or 'Rational'+type,  and then converting to a floating-point type.   If you are defining+your own 'ToRow' instances,  this can be acheived simply by+@'fromRational' '<$>' 'field'@,  although this idiom additionally compatible+with PostgreSQL's @numeric@ type.+ Because 'FromField' is a typeclass,  one may provide conversions to additional Haskell types without modifying postgresql-simple.  This is particularly useful for supporting PostgreSQL types that postgresql-simple@@ -301,12 +309,14 @@ instance FromField Integer where     fromField = atto ok64 $ signed decimal --- | int2, float4+-- | int2, float4    (Uses attoparsec's 'double' routine,  for+--   better accuracy convert to 'Scientific' or 'Rational' first) instance FromField Float where     fromField = atto ok (realToFrac <$> double)       where ok = $(mkCompats [TI.float4,TI.int2]) --- | int2, int4, float4, float8+-- | int2, int4, float4, float8  (Uses attoparsec's 'double' routine,  for+--   better accuracy convert to 'Scientific' or 'Rational' first) instance FromField Double where     fromField = atto ok double       where ok = $(mkCompats [TI.float4,TI.float8,TI.int2,TI.int4])
src/Database/PostgreSQL/Simple/ToField.hs view
@@ -338,14 +338,16 @@         typedRows :: ToRow a => [a] -> [QualifiedIdentifier] -> [Action] -> [Action]         typedRows [] _ _ = error funcname         typedRows (val:vals) types rest =-            typedRow (toRow val) types (litC ',' : untypedRows vals rest)+            typedRow (toRow val) types (multiRows vals rest)          untypedRows :: ToRow a => [a] -> [Action] -> [Action]-        untypedRows [] rest = rest+        untypedRows [] _ = error funcname         untypedRows (val:vals) rest =-            untypedRow (toRow val) $-              interleaveFoldr-                  (untypedRow . toRow)-                  (litC ',')-                  rest-                  vals+            untypedRow (toRow val) (multiRows vals rest)++        multiRows :: ToRow a => [a] -> [Action] -> [Action]+        multiRows vals rest = interleaveFoldr+                                (untypedRow . toRow)+                                (litC ',')+                                rest+                                vals
src/Database/PostgreSQL/Simple/Types.hs view
@@ -139,6 +139,13 @@ instance Hashable QualifiedIdentifier where     hashWithSalt i (QualifiedIdentifier q t) = hashWithSalt i (q, t) +-- | @\"foo.bar\"@ will get turned into+-- @QualifiedIdentifier (Just \"foo\") \"bar\"@,  while @\"foo\"@ will get+-- turned into @QualifiedIdentifier Nothing \"foo\"@.   Note this instance+-- is for convenience,  and does not match postgres syntax.   It+-- only examines the first period character,  and thus cannot be used if the+-- qualifying identifier contains a period for example.+ instance IsString QualifiedIdentifier where     fromString str = let (x,y) = T.break (== '.') (fromString str)                       in if T.null y@@ -173,26 +180,40 @@     deriving (Eq, Ord, Show, Read, Typeable)  -- | Represents a @VALUES@ table literal,  usable as an alternative---   to @executeMany@ and @returning@.  For example:+--   to @executeMany@ and @returning@.  The main advantage is that+--   you can parametrize more than just a single @VALUES@ expression.+--   For example,  here's a query to insert a thing into one table+--   and some attributes of that thing into another,   returning the+--   new id generated by the database: ----- > execute c "INSERT INTO table (key,val) ?"--- >      (Only (Values ["int4","text"]--- >                    [(1,"hello"),(2,"world")])) -----   Issues the following query:+-- > query c [sql|+-- >     WITH new_thing AS (+-- >       INSERT INTO thing (name) VALUES (?) RETURNING id+-- >     ), new_attributes AS (+-- >       INSERT INTO thing_attributes+-- >          SELECT new_thing.id, attrs.*+-- >            FROM new_thing JOIN ? attrs+-- >     ) SELECT * FROM new_thing+-- >  |] ("foo", Values [  "int4", "text"    ]+-- >                    [ ( 1    , "hello" )+-- >                    , ( 2    , "world" ) ]) ----- > INSERT INTO table (key,val) (VALUES (1::"int4",'hello'::"text"),(2,'world'))+--   (Note this example uses writable common table expressions,+--    which were added in PostgreSQL 9.1) -----   When the list of values is empty,  the following query will be issued:+--   The second parameter gets expanded into the following SQL syntax: ----- > INSERT INTO table (key,val) (VALUES (null::"int4",null::"text") LIMIT 0)+-- > (VALUES (1::"int4",'hello'::"text"),(2,'world')) --+--   When the list of attributes is empty,  the second parameter expands to:+--+-- > (VALUES (null::"int4",null::"text") LIMIT 0)+-- --   By contrast, @executeMany@ and @returning@ don't issue the query --   in the empty case, and simply return @0@ and @[]@ respectively.------   The advantage over @executeMany@ is in cases when you want to---   parameterize table literals in addition to other parameters,  as can---   occur with writable common table expressions, for example.+--   This behavior is usually correct given their intended use cases,+--   but would certainly be wrong in the example above. -- --   The first argument is a list of postgresql type names.  Because this --   is turned into a properly quoted identifier,  the type name is case@@ -202,11 +223,10 @@ -- --   You may omit the type names,  however,  if you do so the list --   of values must be non-empty,  and postgresql must be able to infer---   the types of the columns from the surrounding context.   If these---   conditions are not met,  postgresql-simple will throw an exception---   without issuing the query in the former case,  and in the latter---   the postgres server will return an error which will be turned into---   a @SqlError@ exception.+--   the types of the columns from the surrounding context.   If the first+--   condition is not met,  postgresql-simple will throw an exception+--   without issuing the query.   In the second case,  the postgres server+--   will return an error which will be turned into a @SqlError@ exception. -- --   See <http://www.postgresql.org/docs/9.3/static/sql-values.html> for --   more information.
test/Main.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE ScopedTypeVariables #-} import Common import Database.PostgreSQL.Simple.FromField (FromField)-import Database.PostgreSQL.Simple.Types(Query(..))+import Database.PostgreSQL.Simple.Types(Query(..),Values(..)) import Database.PostgreSQL.Simple.HStore import qualified Database.PostgreSQL.Simple.Transaction as ST import Control.Applicative@@ -40,6 +40,7 @@     , TestLabel "JSON"          . testJSON     , TestLabel "Savepoint"     . testSavepoint     , TestLabel "Unicode"       . testUnicode+    , TestLabel "Values"        . testValues     ]  testBytea :: TestEnv -> Test@@ -249,12 +250,30 @@  testUnicode :: TestEnv -> Test testUnicode TestEnv{..} = TestCase $ do-    let q = Query . T.encodeUtf8+    let q = Query . T.encodeUtf8  -- Handle encoding ourselves to ensure+                                  -- the table gets created correctly.     let messages = map Only ["привет","мир"] :: [Only Text]     execute_ conn (q "CREATE TEMPORARY TABLE ру́сский (сообщение TEXT)")     executeMany conn "INSERT INTO ру́сский (сообщение) VALUES (?)" messages     messages' <- query_ conn "SELECT сообщение FROM ру́сский"     sort messages @?= sort messages'++testValues :: TestEnv -> Test+testValues TestEnv{..} = TestCase $ do+    execute_ conn "CREATE TEMPORARY TABLE values_test (x int, y text)"+    test (Values ["int4","text"] [])+    test (Values ["int4","text"] [(1,"hello")])+    test (Values ["int4","text"] [(1,"hello"),(2,"world")])+    test (Values ["int4","text"] [(1,"hello"),(2,"world"),(3,"goodbye")])+    test (Values [] [(1,"hello")])+    test (Values [] [(1,"hello"),(2,"world")])+    test (Values [] [(1,"hello"),(2,"world"),(3,"goodbye")])+  where+    test :: Values (Int, Text) -> Assertion+    test table@(Values _ vals) = do+      execute conn "INSERT INTO values_test ?" (Only table)+      vals' <- query_  conn "DELETE FROM values_test RETURNING *"+      sort vals @?= sort vals'  data TestException   = TestException