0 | module Oracle.Migration.Runner
4 | import Oracle.Types.Migration
14 | ensureMigrationTable : Connection -> IO (Either OracleError ())
15 | ensureMigrationTable conn = do
16 | result <- queryRaw conn
20 | WHERE table_name = 'IDRIS_ORACLE_MIGRATIONS'
33 | CREATE TABLE idris_oracle_migrations (
34 | version NUMBER PRIMARY KEY,
35 | description VARCHAR2(4000) NOT NULL,
36 | applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
48 | listAppliedMigrations : Connection -> IO (Either OracleError (List MigrationInfo))
49 | listAppliedMigrations conn =
50 | ensureMigrationTable conn
52 | result <- queryRaw conn
59 | 'YYYY-MM-DD"T"HH24:MI:SS.FF9'
61 | FROM idris_oracle_migrations
71 | decodeRow : List OracleValue -> Either OracleError MigrationInfo
72 | decodeRow [ OracleNumber version
73 | , OracleString description
74 | , OracleString appliedAt
85 | ("Invalid migration history row: " ++ show row)
86 | "Oracle.Migration.Runner.listAppliedMigrations"
88 | decodeRows : List (List OracleValue) -> IO (Either OracleError (List MigrationInfo))
91 | decodeRows (row :: rows) =
92 | case decodeRow row of
96 | rest <- decodeRows rows
101 | pure (Right (info :: infos))
106 | pendingMigrations : Connection -> List Migration -> IO (Either OracleError (List Migration))
107 | pendingMigrations conn migrations = do
108 | result <- listAppliedMigrations conn
116 | (\migration => not (isMigrationApplied migration applied))
117 | (sortBy compareMigrationVersion migrations)
119 | compareMigrationVersion : Migration -> Migration -> Ordering
120 | compareMigrationVersion a b =
121 | compare (migrationversion a) (migrationversion b)
132 | migrationStatus : Connection -> List Migration -> IO (Either OracleError (List MigrationStatus))
133 | migrationStatus conn migrations = do
134 | result <- listAppliedMigrations conn
138 | Right applied => do
139 | let migrationstatuses =
141 | case findApplied migration applied of
143 | MigrationPending migration
145 | MigrationApplied migration info
147 | (sortBy compareMigrationVersion migrations)
148 | let missingstatuses =
152 | (\info => not (containsVersion info migrations))
157 | migrationstatuses ++ missingstatuses
159 | compareMigrationVersion : Migration -> Migration -> Ordering
160 | compareMigrationVersion a b =
161 | compare (migrationversion a) (migrationversion b)
162 | findApplied : Migration -> List MigrationInfo -> Maybe MigrationInfo
163 | findApplied migration [] =
165 | findApplied migration (migrationinfo :: migrationinfos) =
166 | case sameMigrationVersion migration migrationinfo of
170 | findApplied migration migrationinfos
171 | containsVersion : MigrationInfo -> List Migration -> Bool
172 | containsVersion migrationinfo [] =
174 | containsVersion migrationinfo (migration :: migrations) =
175 | case migrationinfoversion migrationinfo == migrationversion migration of
179 | containsVersion migrationinfo migrations
183 | recordMigration : Connection -> Migration -> IO (Either OracleError ())
184 | recordMigration conn migration =
188 | INSERT INTO idris_oracle_migrations
203 | (OracleNumber (cast (migrationversion migration)))
206 | (OracleString (migrationname migration))
211 | removeMigrationRecord : Connection -> Migration -> IO (Either OracleError ())
212 | removeMigrationRecord conn migration =
216 | DELETE FROM idris_oracle_migrations
217 | WHERE version = :version
221 | (OracleNumber (cast (migrationversion migration)))
235 | runMigrations : Connection -> List Migration -> IO (Either OracleError ())
236 | runMigrations conn migrations = do
237 | pendingresult <- pendingMigrations conn migrations
238 | case pendingresult of
242 | runPending conn pending
244 | runPending : Connection -> List Migration -> IO (Either OracleError ())
247 | runPending conn (migration :: migrations) = do
248 | result <- (migrationup migration) conn
253 | recordresult <- recordMigration conn migration
254 | case recordresult of
258 | commitresult <- commit conn
259 | case commitresult of
263 | runPending conn migrations
276 | rollbackMigration : Connection -> List Migration -> IO (Either OracleError ())
277 | rollbackMigration conn migrations = do
278 | appliedresult <- listAppliedMigrations conn
279 | case appliedresult of
287 | "No migrations have been applied"
288 | "Oracle.Migration.Runner.rollbackMigration"
291 | case latestMigration applied of
297 | "Unable to determine latest migration"
298 | "Oracle.Migration.Runner.rollbackMigration"
301 | case findMigration latest migrations of
307 | ( "Migration definition not found for applied version "
308 | ++ show (migrationinfoversion latest)
310 | "Oracle.Migration.Runner.rollbackMigration"
313 | rollback conn migration
315 | latestMigration : List MigrationInfo -> Maybe MigrationInfo
316 | latestMigration [] =
318 | latestMigration (info :: infos) =
321 | (\current, candidate =>
322 | case migrationinfoversion candidate > migrationinfoversion current of
330 | findMigration : MigrationInfo -> List Migration -> Maybe Migration
331 | findMigration _ [] =
333 | findMigration migrationinfo (migration :: migrations) =
334 | case migrationinfoversion migrationinfo == migrationversion migration of
338 | findMigration migrationinfo migrations
339 | rollback : Connection -> Migration -> IO (Either OracleError ())
340 | rollback conn migration = do
341 | result <- (migrationdown migration) conn
346 | removeResult <- removeMigrationRecord conn migration
347 | case removeResult of