mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-28 23:34:51 +09:00
I made upgrades to the DB migration system in Funbot, apply them here too
This commit is contained in:
parent
b8681e2681
commit
3b4bd2a5e8
5 changed files with 38 additions and 38 deletions
|
@ -124,7 +124,7 @@ data Unique = Unique
|
||||||
, uniqueFields :: [FieldName]
|
, uniqueFields :: [FieldName]
|
||||||
}
|
}
|
||||||
|
|
||||||
type SchemaT b m a = ReaderT (SchemaBackend b) (ReaderT b m) a
|
type SchemaT b m = ReaderT (SchemaBackend b) (ReaderT b m)
|
||||||
|
|
||||||
-- | Ideally we'd make the @backend@ provide schema related specifics. The
|
-- | Ideally we'd make the @backend@ provide schema related specifics. The
|
||||||
-- problem is that e.g. @SqlBackend@ is already defined in @persistent@ and
|
-- problem is that e.g. @SqlBackend@ is already defined in @persistent@ and
|
||||||
|
@ -137,13 +137,15 @@ type SchemaT b m a = ReaderT (SchemaBackend b) (ReaderT b m) a
|
||||||
-- explicitly specifying the schema backend and using 'lift' for data manip.
|
-- explicitly specifying the schema backend and using 'lift' for data manip.
|
||||||
class PersistSchema backend where
|
class PersistSchema backend where
|
||||||
data SchemaBackend backend -- :: *
|
data SchemaBackend backend -- :: *
|
||||||
|
hasSchemaEntity
|
||||||
|
:: MonadIO m => SchemaT backend m Bool
|
||||||
addEntity
|
addEntity
|
||||||
:: MonadIO m => Entity -> SchemaT backend m ()
|
:: MonadIO m => Entity -> SchemaT backend m ()
|
||||||
removeEntity
|
removeEntity
|
||||||
:: MonadIO m => EntityName -> SchemaT backend m ()
|
:: MonadIO m => EntityName -> SchemaT backend m ()
|
||||||
addField
|
addField
|
||||||
:: MonadIO m
|
:: MonadIO m
|
||||||
=> EntityName -> Field -> Maybe Text -> SchemaT backend m ()
|
=> EntityName -> Maybe Text -> Field -> SchemaT backend m ()
|
||||||
renameField
|
renameField
|
||||||
:: MonadIO m
|
:: MonadIO m
|
||||||
=> EntityName -> FieldName -> FieldName -> SchemaT backend m ()
|
=> EntityName -> FieldName -> FieldName -> SchemaT backend m ()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- This file is part of Vervis.
|
{- This file is part of Vervis.
|
||||||
-
|
-
|
||||||
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
- Written in 2016, 2017 by fr33domlover <fr33domlover@riseup.net>.
|
||||||
-
|
-
|
||||||
- ♡ Copying is an act of love. Please copy, reuse and share.
|
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||||
-
|
-
|
||||||
|
@ -79,6 +79,11 @@ idSql = "id SERIAL8 PRIMARY KEY UNIQUE"
|
||||||
schemaBackend :: SchemaBackend SqlBackend
|
schemaBackend :: SchemaBackend SqlBackend
|
||||||
schemaBackend = SqlSchemaBackend
|
schemaBackend = SqlSchemaBackend
|
||||||
{ ssbRefType = SqlInt64
|
{ ssbRefType = SqlInt64
|
||||||
|
, ssbDoesTableExist =
|
||||||
|
"SELECT COUNT(*) FROM pg_catalog.pg_tables \
|
||||||
|
\ WHERE schemaname != 'pg_catalog' AND \
|
||||||
|
\ schemaname != 'information_schema' AND \
|
||||||
|
\ tablename = ?"
|
||||||
, ssbCreateTable = \ table columns -> mconcat
|
, ssbCreateTable = \ table columns -> mconcat
|
||||||
[ "CREATE TABLE ", table2sql table, " ("
|
[ "CREATE TABLE ", table2sql table, " ("
|
||||||
, idSql
|
, idSql
|
||||||
|
|
|
@ -34,9 +34,10 @@ import Data.Char (isUpper, toLower)
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
import Data.Maybe (isJust)
|
import Data.Maybe (isJust)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Database.Persist.Sql (Sql, SqlBackend, rawExecute)
|
import Database.Persist.Sql hiding (FieldType, Entity, Column)
|
||||||
import Database.Persist.Types (SqlType)
|
import Database.Persist.Types (SqlType)
|
||||||
|
|
||||||
|
import qualified Data.Conduit.List as CL (head)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
import Database.Persist.Schema
|
import Database.Persist.Schema
|
||||||
|
@ -56,6 +57,16 @@ data Column = Column
|
||||||
exec :: MonadIO m => Sql -> SchemaT SqlBackend m ()
|
exec :: MonadIO m => Sql -> SchemaT SqlBackend m ()
|
||||||
exec t = lift $ rawExecute t []
|
exec t = lift $ rawExecute t []
|
||||||
|
|
||||||
|
inquire
|
||||||
|
:: MonadIO m => Sql -> [PersistValue] -> SchemaT SqlBackend m PersistValue
|
||||||
|
inquire t vs = lift $ withRawQuery t vs $ do
|
||||||
|
l <- CL.head
|
||||||
|
case l of
|
||||||
|
Just [x] -> return x
|
||||||
|
Just [] -> error $ "inquire: got empty list " ++ show t
|
||||||
|
Just xs -> error $ "inquire: got multiple values " ++ show xs ++ show t
|
||||||
|
Nothing -> error $ "inquire: got nothing " ++ show t
|
||||||
|
|
||||||
camelWords :: Text -> [Text]
|
camelWords :: Text -> [Text]
|
||||||
camelWords ident =
|
camelWords ident =
|
||||||
let low = toLower
|
let low = toLower
|
||||||
|
@ -100,6 +111,7 @@ mkcolumn ssb (Field name typ mnull) = Column
|
||||||
instance PersistSchema SqlBackend where
|
instance PersistSchema SqlBackend where
|
||||||
data SchemaBackend SqlBackend = SqlSchemaBackend
|
data SchemaBackend SqlBackend = SqlSchemaBackend
|
||||||
{ ssbRefType :: SqlType
|
{ ssbRefType :: SqlType
|
||||||
|
, ssbDoesTableExist :: Sql
|
||||||
, ssbCreateTable :: TableName -> [Column] -> Sql
|
, ssbCreateTable :: TableName -> [Column] -> Sql
|
||||||
, ssbRenameTable :: TableName -> TableName -> Sql
|
, ssbRenameTable :: TableName -> TableName -> Sql
|
||||||
, ssbDropTable :: TableName -> Sql
|
, ssbDropTable :: TableName -> Sql
|
||||||
|
@ -119,6 +131,16 @@ instance PersistSchema SqlBackend where
|
||||||
:: TableName -> ConstraintName -> ConstraintName -> Sql
|
:: TableName -> ConstraintName -> ConstraintName -> Sql
|
||||||
, ssbDropConstraint :: TableName -> ConstraintName -> Sql
|
, ssbDropConstraint :: TableName -> ConstraintName -> Sql
|
||||||
}
|
}
|
||||||
|
hasSchemaEntity = do
|
||||||
|
ssb <- ask
|
||||||
|
let table =
|
||||||
|
toPersistValue $ unTableName $ entity2table $ EntityName $
|
||||||
|
T.pack "SchemaVersion"
|
||||||
|
v <- inquire (ssbDoesTableExist ssb) [table]
|
||||||
|
case v of
|
||||||
|
PersistInt64 1 -> return True
|
||||||
|
PersistInt64 0 -> return False
|
||||||
|
_ -> error "hasSchemaEntity: count inquiry didn't return a number"
|
||||||
addEntity (Entity name fields uniques) = do
|
addEntity (Entity name fields uniques) = do
|
||||||
ssb <- ask
|
ssb <- ask
|
||||||
exec $
|
exec $
|
||||||
|
@ -127,7 +149,7 @@ instance PersistSchema SqlBackend where
|
||||||
removeEntity name = do
|
removeEntity name = do
|
||||||
ssb <- ask
|
ssb <- ask
|
||||||
exec $ ssbDropTable ssb $ entity2table name
|
exec $ ssbDropTable ssb $ entity2table name
|
||||||
addField ent (Field name typ mnull) mdef = do
|
addField ent mdef (Field name typ mnull) = do
|
||||||
ssb <- ask
|
ssb <- ask
|
||||||
exec $
|
exec $
|
||||||
ssbAddColumn ssb
|
ssbAddColumn ssb
|
||||||
|
|
|
@ -28,46 +28,16 @@ import Database.Persist.Sql (SqlBackend, toSqlKey)
|
||||||
|
|
||||||
import Database.Persist.Schema
|
import Database.Persist.Schema
|
||||||
import Database.Persist.Schema.PostgreSQL (schemaBackend)
|
import Database.Persist.Schema.PostgreSQL (schemaBackend)
|
||||||
|
import Database.Persist.Migration
|
||||||
|
|
||||||
import Vervis.Model
|
import Vervis.Model
|
||||||
|
|
||||||
key :: SchemaVersionId
|
|
||||||
key = toSqlKey 1
|
|
||||||
|
|
||||||
getDbSchemaVersion :: MonadIO m => ReaderT SqlBackend m (Maybe Int)
|
|
||||||
getDbSchemaVersion = fmap schemaVersionNumber <$> get key
|
|
||||||
|
|
||||||
setDbSchemaVersion :: MonadIO m => Int -> ReaderT SqlBackend m ()
|
|
||||||
setDbSchemaVersion v = repsert key $ SchemaVersion v
|
|
||||||
|
|
||||||
-- | Run the migration system. The second parameter is the list of migration
|
|
||||||
-- actions in chronological order. The migration process is:
|
|
||||||
--
|
|
||||||
-- * Check the schema version of the DB
|
|
||||||
-- * Compare to the schema version of the app, which is the length of the list
|
|
||||||
-- * If any migrations are required, run them
|
|
||||||
-- * Update the schema version in the DB
|
|
||||||
runMigrations
|
|
||||||
:: MonadIO m
|
|
||||||
=> SchemaBackend SqlBackend
|
|
||||||
-> [SchemaT SqlBackend m ()]
|
|
||||||
-> ReaderT SqlBackend m ()
|
|
||||||
runMigrations sb migrations = do
|
|
||||||
dver <- fromMaybe 0 <$> getDbSchemaVersion
|
|
||||||
let aver = length migrations
|
|
||||||
case compare aver dver of
|
|
||||||
LT -> error "Older app version running with newer DB schema version"
|
|
||||||
EQ -> return ()
|
|
||||||
GT -> do
|
|
||||||
let migs = drop dver migrations
|
|
||||||
runReaderT (sequence migs) sb
|
|
||||||
setDbSchemaVersion aver
|
|
||||||
|
|
||||||
changes :: MonadIO m => [SchemaT SqlBackend m ()]
|
changes :: MonadIO m => [SchemaT SqlBackend m ()]
|
||||||
changes =
|
changes =
|
||||||
[ addField "Workflow"
|
[ addField "Workflow"
|
||||||
(Field "scope" (FTPrim SqlString) NotNull)
|
|
||||||
(Just "'WSSharer'")
|
(Just "'WSSharer'")
|
||||||
|
(Field "scope" (FTPrim SqlString) NotNull)
|
||||||
|
--, lift $ do
|
||||||
]
|
]
|
||||||
|
|
||||||
migrateDB :: MonadIO m => ReaderT SqlBackend m ()
|
migrateDB :: MonadIO m => ReaderT SqlBackend m ()
|
||||||
|
|
|
@ -83,6 +83,7 @@ library
|
||||||
Database.Persist.Local.Sql
|
Database.Persist.Local.Sql
|
||||||
Database.Persist.Local.Sql.Orphan.Common
|
Database.Persist.Local.Sql.Orphan.Common
|
||||||
Database.Persist.Local.Sql.Orphan.PersistQueryForest
|
Database.Persist.Local.Sql.Orphan.PersistQueryForest
|
||||||
|
Database.Persist.Migration
|
||||||
Database.Persist.Schema
|
Database.Persist.Schema
|
||||||
Database.Persist.Schema.PostgreSQL
|
Database.Persist.Schema.PostgreSQL
|
||||||
Database.Persist.Schema.Sql
|
Database.Persist.Schema.Sql
|
||||||
|
|
Loading…
Reference in a new issue