{-# LANGUAGE OverloadedStrings #-} module Database.Schema.Migrations.Backend.HDBC ( hdbcBackend ) where import Database.HDBC ( quickQuery' , fromSql , toSql , IConnection(getTables, run, runRaw) , commit , rollback , disconnect ) import Database.Schema.Migrations.Backend ( Backend(..) , rootMigrationName ) import Database.Schema.Migrations.Migration ( Migration(..) , newMigration ) import Data.Text ( Text ) import Data.String.Conversions ( cs, (<>) ) import Control.Applicative ( (<$>) ) import Data.Time.Clock (getCurrentTime) migrationTableName :: Text migrationTableName = "installed_migrations" createSql :: Text createSql = "CREATE TABLE " <> migrationTableName <> " (migration_id TEXT)" revertSql :: Text revertSql = "DROP TABLE " <> migrationTableName -- |General Backend constructor for all HDBC connection implementations. hdbcBackend :: (IConnection conn) => conn -> Backend hdbcBackend conn = Backend { isBootstrapped = elem (cs migrationTableName) <$> getTables conn , getBootstrapMigration = do ts <- getCurrentTime return $ (newMigration rootMigrationName) { mApply = createSql , mRevert = Just revertSql , mDesc = Just "Migration table installation" , mTimestamp = Just ts } , applyMigration = \m -> do runRaw conn (cs $ mApply m) _ <- run conn (cs $ "INSERT INTO " <> migrationTableName <> " (migration_id) VALUES (?)") [toSql $ mId m] return () , revertMigration = \m -> do case mRevert m of Nothing -> return () Just query -> runRaw conn (cs query) -- Remove migration from installed_migrations in either case. _ <- run conn (cs $ "DELETE FROM " <> migrationTableName <> " WHERE migration_id = ?") [toSql $ mId m] return () , getMigrations = do results <- quickQuery' conn (cs $ "SELECT migration_id FROM " <> migrationTableName) [] return $ map (fromSql . head) results , commitBackend = commit conn , rollbackBackend = rollback conn , disconnectBackend = disconnect conn }