Skip to content

Commit

Permalink
Add FromField and ToField instance for Data.UUID
Browse files Browse the repository at this point in the history
The implementation is based on `postgresql-simple`[1][2]. `uuid-types`[3] is used
because it contains fewer transitive dependencies, but `uuid`[4] is used
as a dependency for the test case.

This fixes nurpax#62.

[1]: https://hackage.haskell.org/package/postgresql-simple-0.5.3.0/docs/Database-PostgreSQL-Simple-FromField.html#t:FromField
[2]: https://hackage.haskell.org/package/postgresql-simple-0.6.2/docs/Database-PostgreSQL-Simple-ToField.html#t:ToField
[3]: https://hackage.haskell.org/package/uuid-types-1.0.3
[4]: https://hackage.haskell.org/package/uuid
  • Loading branch information
mkoppmann committed Oct 25, 2020
1 parent 4939058 commit 37c9136
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Database/SQLite/Simple/FromField.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import Data.Time (UTCTime, Day)
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import Data.Typeable (Typeable, typeOf)
import Data.UUID.Types (UUID)
import qualified Data.UUID.Types as UUID
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Float (double2Float)

Expand Down Expand Up @@ -185,6 +187,13 @@ instance FromField UTCTime where

fromField f = returnError ConversionFailed f "expecting SQLText column type"

instance FromField UUID where
fromField f@(Field (SQLText t) _) =
case UUID.fromText t of
Just uuid -> Ok uuid
Nothing -> returnError ConversionFailed f "couldn't parse UUID field"

fromField f = returnError ConversionFailed f "expecting SQLText column type"

instance FromField Day where
fromField f@(Field (SQLText t) _) =
Expand Down
6 changes: 6 additions & 0 deletions Database/SQLite/Simple/ToField.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import qualified Data.Text.Encoding as T
import Data.Time (Day, UTCTime)
import Data.UUID.Types (UUID)
import qualified Data.UUID.Types as UUID
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Float

Expand Down Expand Up @@ -132,6 +134,10 @@ instance ToField UTCTime where
toField = SQLText . T.decodeUtf8 . toByteString . utcTimeToBuilder
{-# INLINE toField #-}

instance ToField UUID where
toField = SQLText . UUID.toText
{-# INLINE toField #-}

instance ToField Day where
toField = SQLText . T.decodeUtf8 . toByteString . dayToBuilder
{-# INLINE toField #-}
Expand Down
2 changes: 2 additions & 0 deletions sqlite-simple.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Library
text >= 0.11,
time,
transformers,
uuid-types >= 1.0.0,
Only >= 0.1 && < 0.1.1

default-extensions:
Expand Down Expand Up @@ -108,3 +109,4 @@ test-suite test
, direct-sqlite
, text
, time
, uuid
1 change: 1 addition & 0 deletions test/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ tests =
, TestLabel "Simple" . testSimpleQueryCov
, TestLabel "Simple" . testSimpleStrings
, TestLabel "Simple" . testSimpleChanges
, TestLabel "Simple" . testSimpleUUID
, TestLabel "ParamConv" . testParamConvNull
, TestLabel "ParamConv" . testParamConvInt
, TestLabel "ParamConv" . testParamConvIntWidths
Expand Down
15 changes: 15 additions & 0 deletions test/Simple.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Simple (
, testSimpleQueryCov
, testSimpleStrings
, testSimpleChanges
, testSimpleUUID
) where

import qualified Data.ByteString as BS
Expand All @@ -24,6 +25,8 @@ import Data.ByteString.Lazy.Char8 ()
import qualified Data.Text as T
import qualified Data.Text.Lazy as LT
import Data.Time (UTCTime, Day)
import Data.UUID (UUID)
import qualified Data.UUID.V4 as UUID

import Common

Expand Down Expand Up @@ -154,6 +157,18 @@ testSimpleMultiInsert TestEnv{..} = TestCase $ do
rows <- query_ conn "SELECT id,t1,t2 FROM test_multi_insert" :: IO [(Int, String, String)]
[(1, "foo", "bar"), (2, "baz", "bat")] @=? rows

testSimpleUUID :: TestEnv -> Test
testSimpleUUID TestEnv{..} = TestCase $ do
uuids <- sequenceA $ replicate 5 UUID.nextRandom
execute_ conn "CREATE TABLE uuids (id UUID)"
mapM_ (execute conn "INSERT INTO uuids (id) VALUES (?)" . Only) uuids
ids <- query_ conn "SELECT id from uuids" :: IO [Only UUID]
mapM_ matchIds (zip uuids ids)
where
matchIds (uuid, Only uid) = do
uuid @=? uid


testSimpleUTCTime :: TestEnv -> Test
testSimpleUTCTime TestEnv{..} = TestCase $ do
-- Time formats understood by sqlite: http://sqlite.org/lang_datefunc.html
Expand Down

0 comments on commit 37c9136

Please sign in to comment.