packages feed

hasql-migration 0.1.3 → 0.2.0

raw patch · 5 files changed

+72/−79 lines, 5 filesdep +cryptonitedep +memorydep −base64-bytestringdep −cryptohashdep ~hasqldep ~hasql-transactionPVP ok

version bump matches the API change (PVP)

Dependencies added: cryptonite, memory

Dependencies removed: base64-bytestring, cryptohash

Dependency ranges changed: hasql, hasql-transaction

API changes (from Hackage documentation)

- Hasql.Migration: MigrationError :: a -> MigrationResult a
- Hasql.Migration: MigrationSuccess :: MigrationResult a
- Hasql.Migration: data MigrationResult a
- Hasql.Migration: instance GHC.Classes.Eq a => GHC.Classes.Eq (Hasql.Migration.MigrationResult a)
- Hasql.Migration: instance GHC.Classes.Ord a => GHC.Classes.Ord (Hasql.Migration.MigrationResult a)
- Hasql.Migration: instance GHC.Read.Read a => GHC.Read.Read (Hasql.Migration.MigrationResult a)
- Hasql.Migration: instance GHC.Show.Show a => GHC.Show.Show (Hasql.Migration.MigrationResult a)
+ Hasql.Migration: ChecksumMismatch :: String -> MigrationError
+ Hasql.Migration: NotInitialised :: MigrationError
+ Hasql.Migration: ScriptChanged :: String -> MigrationError
+ Hasql.Migration: ScriptMissing :: String -> MigrationError
+ Hasql.Migration: data MigrationError
+ Hasql.Migration: instance GHC.Classes.Eq Hasql.Migration.MigrationError
+ Hasql.Migration: instance GHC.Classes.Ord Hasql.Migration.MigrationError
+ Hasql.Migration: instance GHC.Read.Read Hasql.Migration.MigrationError
+ Hasql.Migration: instance GHC.Show.Show Hasql.Migration.MigrationError
- Hasql.Migration: runMigration :: MigrationCommand -> Transaction (MigrationResult String)
+ Hasql.Migration: runMigration :: MigrationCommand -> Transaction (Maybe MigrationError)

Files

hasql-migration.cabal view
@@ -1,5 +1,5 @@ name:                       hasql-migration-version:                    0.1.3+version:                    0.2.0 synopsis:                   PostgreSQL Schema Migrations homepage:                   https://github.com/tvh/hasql-migration Bug-reports:                https://github.com/tvh/hasql-migration/issues@@ -7,12 +7,12 @@ license-file:               License author:                     Timo von Holtz <tvh@tvholtz.de> maintainer:                 Timo von Holtz <tvh@tvholtz.de>-copyright:                  Timo von Holtz, Andreas Meingast+copyright:                  Timo von Holtz, Andreas Meingast, Sumit Raja category:                   Database build-type:                 Simple cabal-version:              >= 1.10 description:                A PostgreSQL-simple schema migration utility-+tested-with:                GHC==8.0.1, GHC==8.2.2, GHC==8.4.3 extra-source-files:         License                             Readme.markdown @@ -26,34 +26,35 @@     type:                   git     location:               git://github.com/tvh/hasql-migration -Library+library     exposed-modules:        Hasql.Migration                             Hasql.Migration.Util     hs-source-dirs:         src     ghc-options:            -Wall -fwarn-tabs -fwarn-incomplete-uni-patterns     default-language:       Haskell2010-    build-depends:          base                        >= 4.7      && < 5.0,-                            base64-bytestring           >= 1.0      && < 1.1,-                            bytestring                  >= 0.10     && < 0.11,-                            contravariant               >= 1.3      && < 1.5,-                            cryptohash                  >= 0.11     && < 0.12,-                            data-default-class          >= 0.0.1    && < 0.2,-                            directory                   >= 1.2      && < 1.4,-                            hasql                       >= 0.19     && < 0.20,-                            hasql-transaction           >= 0.5      && < 0.6,-                            text                        >= 1.2      && < 1.3,-                            time                        >= 1.4      && < 1.7+    build-depends:          base                        >= 4.7 && < 5,+                            bytestring                  >= 0.10,+                            contravariant               >= 1.3,+                            cryptonite                  >= 0.11,+                            data-default-class          >= 0.0.1,+                            directory                   >= 1.2,+                            hasql                       >= 1.3,+                            hasql-transaction           >= 0.7,+                            memory,+                            text                        >= 1.2,+                            time                        >= 1.4 -test-suite tests+test-suite hasql-migration-test     main-is:                Main.hs     hs-source-dirs:         test     ghc-options:            -Wall -fwarn-tabs -fwarn-incomplete-uni-patterns+    other-modules:          Hasql.MigrationTest     default-language:       Haskell2010     type:                   exitcode-stdio-1.0-    build-depends:          base                        >= 4.7      && < 5.0,-                            bytestring                  >= 0.10     && < 0.11,-                            hasql                       >= 0.19     && < 0.20,+    build-depends:          base                        >= 4.7 && < 5,+                            bytestring                  >= 0.10,+                            hasql                       >= 0.19,                             hasql-migration,-                            hasql-transaction           >= 0.5      && < 0.6,-                            hspec                       >= 2.2      && < 2.4,-                            transformers                >= 0.3      && < 0.6+                            hasql-transaction           >= 0.5,+                            hspec                       >= 2.2,+                            transformers                >= 0.3
src/Hasql/Migration.hs view
@@ -23,7 +23,7 @@      -- * Migration types     , MigrationCommand(..)-    , MigrationResult(..)+    , MigrationError(..)     , ScriptName     , Checksum @@ -35,20 +35,18 @@     ) where  import Control.Arrow-import Control.Applicative+import Crypto.Hash (hashWith, MD5(..))+import Data.ByteArray.Encoding import Data.Default.Class import Data.Functor.Contravariant import Data.List (isPrefixOf, sort)-import Data.Monoid-import Data.Traversable (forM) import Data.Time (LocalTime)+import Data.Traversable (forM) import Hasql.Migration.Util (existsTable)-import Hasql.Query+import Hasql.Statement import Hasql.Transaction import System.Directory (getDirectoryContents)-import qualified Crypto.Hash.MD5 as MD5 (hash) import qualified Data.ByteString as BS (ByteString, readFile)-import qualified Data.ByteString.Base64 as B64 (encode) import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Hasql.Decoders as Decoders@@ -59,10 +57,10 @@ -- Returns 'MigrationSuccess' if the provided 'MigrationCommand' executes -- without error. If an error occurs, execution is stopped and -- a 'MigrationError' is returned.-runMigration :: MigrationCommand -> Transaction (MigrationResult String)+runMigration :: MigrationCommand -> Transaction (Maybe MigrationError) runMigration cmd = case cmd of     MigrationInitialization ->-        initializeSchema >> return MigrationSuccess+        initializeSchema >> return Nothing     MigrationScript name contents ->         executeMigration name contents     MigrationValidation validationCmd ->@@ -87,21 +85,20 @@ scriptsInDirectory dir =     fmap (sort . filter (\x -> not $ "." `isPrefixOf` x))         (getDirectoryContents dir)- -- | Executes a generic SQL migration for the provided script 'name' with -- content 'contents'.-executeMigration :: ScriptName -> BS.ByteString -> Transaction (MigrationResult String)+executeMigration :: ScriptName -> BS.ByteString -> Transaction (Maybe MigrationError) executeMigration name contents = do     let checksum = md5Hash contents     checkScript name checksum >>= \case         ScriptOk -> do-            return MigrationSuccess+            return Nothing         ScriptNotExecuted -> do             sql contents-            query (name, checksum) (statement q (contramap (first T.pack) def) Decoders.unit False)-            return MigrationSuccess+            statement (name, checksum) (Statement q (contramap (first T.pack) def) Decoders.unit False)+            return Nothing         ScriptModified _ -> do-            return (MigrationError name)+            return (Just $ ScriptChanged name)     where         q = "insert into schema_migrations(filename, checksum) values($1, $2)" @@ -123,25 +120,25 @@ -- * 'MigrationInitialization': validate the presence of the meta-information -- table. -- * 'MigrationValidation': always succeeds.-executeValidation :: MigrationCommand -> Transaction (MigrationResult String)+executeValidation :: MigrationCommand -> Transaction (Maybe MigrationError) executeValidation cmd = case cmd of     MigrationInitialization ->         existsTable "schema_migrations" >>= \r -> return $ if r-            then MigrationSuccess-            else MigrationError "No such table: schema_migrations"+            then Nothing+            else (Just NotInitialised)     MigrationScript name contents ->         validate name contents     MigrationValidation _ ->-        return MigrationSuccess+        return Nothing     where         validate name contents =             checkScript name (md5Hash contents) >>= \case                 ScriptOk -> do-                    return MigrationSuccess+                    return Nothing                 ScriptNotExecuted -> do-                    return (MigrationError $ "Missing: " ++ name)+                    return (Just $ ScriptMissing name)                 ScriptModified _ -> do-                    return (MigrationError $ "Checksum mismatch: " ++ name)+                    return (Just $ ChecksumMismatch name)  -- | Checks the status of the script with the given name 'name'. -- If the script has already been executed, the checksum of the script@@ -150,7 +147,7 @@ -- will be executed and its meta-information will be recorded. checkScript :: ScriptName -> Checksum -> Transaction CheckScriptResult checkScript name checksum =-    query name (statement q (contramap T.pack (Encoders.value def)) (Decoders.maybeRow (Decoders.value def)) False) >>= \case+    statement name (Statement q (contramap T.pack (Encoders.param def)) (Decoders.rowMaybe (Decoders.column def)) False) >>= \case         Nothing ->             return ScriptNotExecuted         Just actualChecksum | checksum == actualChecksum ->@@ -166,7 +163,7 @@ -- | Calculates the MD5 checksum of the provided bytestring in base64 -- encoding. md5Hash :: BS.ByteString -> Checksum-md5Hash = T.decodeUtf8 . B64.encode . MD5.hash+md5Hash = T.decodeUtf8 . convertToBase Base64 . hashWith MD5  -- | The checksum type of a migration script. type Checksum = T.Text@@ -198,18 +195,13 @@     -- ^ The script has not been executed, yet. This is good.     deriving (Show, Eq, Read, Ord) --- | A sum-type denoting the result of a migration.-data MigrationResult a-    = MigrationError a-    -- ^ There was an error in script migration.-    | MigrationSuccess-    -- ^ All scripts have been executed successfully.-    deriving (Show, Eq, Read, Ord)+-- | Errors that could occur when a migration is validated or performed+data MigrationError = ScriptChanged String | NotInitialised | ScriptMissing String | ChecksumMismatch String deriving (Show, Eq, Read, Ord)  -- | Produces a list of all executed 'SchemaMigration's. getMigrations :: Transaction [SchemaMigration] getMigrations =-    query () $ statement q def (Decoders.rowsList decodeSchemaMigration) False+    statement () $ Statement q def (Decoders.rowList decodeSchemaMigration) False     where         q = mconcat             [ "select filename, checksum, executed_at "@@ -233,6 +225,6 @@ decodeSchemaMigration :: Decoders.Row SchemaMigration decodeSchemaMigration =     SchemaMigration-    <$> Decoders.value def-    <*> Decoders.value def-    <*> Decoders.value def+    <$> Decoders.column def+    <*> Decoders.column def+    <*> Decoders.column def
src/Hasql/Migration/Util.hs view
@@ -16,17 +16,17 @@     ( existsTable     ) where -import           Hasql.Query+import           Hasql.Statement import qualified Hasql.Encoders as Encoders import qualified Hasql.Decoders as Decoders-import           Hasql.Transaction (query, Transaction)+import           Hasql.Transaction (statement, Transaction) import Data.Text (Text) import Data.Default.Class  -- | Checks if the table with the given name exists in the database. existsTable :: Text -> Transaction Bool existsTable table =-    fmap (not . null) $ query table q+    fmap (not . null) $ statement table q     where-        q = statement sql (Encoders.value def) (Decoders.rowsList (Decoders.value Decoders.int8)) False-        sql = "select count(relname) from pg_class where relname = $1"+        q = Statement sql (Encoders.param def) (Decoders.rowList (Decoders.column Decoders.int8)) False+        sql = "select relname from pg_class where relname = $1"
test/Hasql/MigrationTest.hs view
@@ -14,7 +14,7 @@  module Hasql.MigrationTest where -import           Hasql.Session                        (run, Error)+import           Hasql.Session                        (run, QueryError) import           Hasql.Connection import qualified Hasql.Transaction                    as Tx import qualified Hasql.Transaction.Sessions           as Tx@@ -23,7 +23,7 @@ import           Test.Hspec                           (Spec, describe, it,                                                        shouldBe, runIO) -runTx :: Connection -> Tx.Transaction a -> IO (Either Error a)+runTx :: Connection -> Tx.Transaction a -> IO (Either QueryError a) runTx con act = do     run (Tx.transaction Tx.ReadCommitted Tx.Write act) con @@ -36,15 +36,15 @@      it "initializes a database" $ do         r <- runTx con $ runMigration $ MigrationInitialization-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "creates the schema_migrations table" $ do-        r <- runTx con $ existsTable "schema_migration"+        r <- runTx con $ existsTable "schema_migrations"         r `shouldBe` Right True      it "executes a migration script" $ do         r <- runTx con $ runMigration $ migrationScript-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "creates the table from the executed script" $ do         r <- runTx con $ existsTable "t1"@@ -52,15 +52,15 @@      it "skips execution of the same migration script" $ do         r <- runTx con $ runMigration $ migrationScript-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "reports an error on a different checksum for the same script" $ do         r <- runTx con $ runMigration $ migrationScriptAltered-        r `shouldBe` Right (MigrationError "test.sql")+        r `shouldBe` Right (Just (ScriptChanged "test.sql"))      it "executes migration scripts inside a folder" $ do         r <- runTx con $ runMigration $ migrationDir-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "creates the table from the executed scripts" $ do         r <- runTx con $ existsTable "t2"@@ -68,7 +68,7 @@      it "executes a file based migration script" $ do         r <- runTx con $ runMigration $ migrationFile-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "creates the table from the executed scripts" $ do         r <- runTx con $ existsTable "t3"@@ -76,19 +76,19 @@      it "validates initialization" $ do         r <- runTx con $ runMigration $ (MigrationValidation MigrationInitialization)-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "validates an executed migration script" $ do         r <- runTx con $ runMigration $ (MigrationValidation migrationScript)-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "validates all scripts inside a folder" $ do         r <- runTx con $ runMigration $ (MigrationValidation migrationDir)-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "validates an executed migration file" $ do         r <- runTx con $ runMigration $ (MigrationValidation migrationFile)-        r `shouldBe` Right MigrationSuccess+        r `shouldBe` Right Nothing      it "gets a list of executed migrations" $ do         r <- runTx con getMigrations
test/Main.hs view
@@ -8,7 +8,7 @@ -- Stability   : experimental -- Portability : GHC ----- The test entry-point for postgresql-simple-migration.+-- The test entry-point for hasql-migration.  {-# LANGUAGE OverloadedStrings #-} @@ -18,11 +18,11 @@  import Hasql.Connection import Hasql.MigrationTest-import           Test.Hspec                               (hspec)+import Test.Hspec (hspec)  main :: IO () main = do-    con <- acquire "dbname=test"-    case con of+    conE <- acquire "dbname=test"+    case conE of       Right con -> hspec (migrationSpec con)       Left err -> putStrLn $ show err