Remove "function" in favor of () => {}
[oweals/peertube.git] / server / initializers / migrator.ts
1 import * as path from 'path'
2 import * as Promise from 'bluebird'
3
4 import { database as db } from './database'
5 import { LAST_MIGRATION_VERSION } from './constants'
6 import { logger, readdirPromise } from '../helpers'
7
8 function migrate () {
9   const p = db.sequelize.getQueryInterface().showAllTables()
10     .then(tables => {
11       // No tables, we don't need to migrate anything
12       // The installer will do that
13       if (tables.length === 0) throw null
14     })
15     .then(() => {
16       return db.Application.loadMigrationVersion()
17     })
18     .then(actualVersion => {
19       if (actualVersion === null) {
20         return db.Application.create({ migrationVersion: 0 }).then(() => 0)
21       }
22
23       return actualVersion
24     })
25     .then(actualVersion => {
26       // No need migrations, abort
27       if (actualVersion >= LAST_MIGRATION_VERSION) throw null
28
29       return actualVersion
30     })
31     .then(actualVersion => {
32       // If there are a new migration scripts
33       logger.info('Begin migrations.')
34
35       return getMigrationScripts().then(migrationScripts => ({ actualVersion, migrationScripts }))
36     })
37     .then(({ actualVersion, migrationScripts }) => {
38       return Promise.each(migrationScripts, entity => executeMigration(actualVersion, entity))
39     })
40     .then(() => {
41       logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
42     })
43     .catch(err => {
44       if (err === null) return undefined
45
46       throw err
47     })
48
49   return p
50 }
51
52 // ---------------------------------------------------------------------------
53
54 export {
55   migrate
56 }
57
58 // ---------------------------------------------------------------------------
59
60 function getMigrationScripts () {
61   return readdirPromise(path.join(__dirname, 'migrations')).then(files => {
62     const filesToMigrate: {
63       version: string,
64       script: string
65     }[] = []
66
67     files.forEach(file => {
68       // Filename is something like 'version-blabla.js'
69       const version = file.split('-')[0]
70       filesToMigrate.push({
71         version,
72         script: file
73       })
74     })
75
76     return filesToMigrate
77   })
78 }
79
80 function executeMigration (actualVersion: number, entity: { version: string, script: string }) {
81   const versionScript = parseInt(entity.version, 10)
82
83   // Do not execute old migration scripts
84   if (versionScript <= actualVersion) return undefined
85
86   // Load the migration module and run it
87   const migrationScriptName = entity.script
88   logger.info('Executing %s migration script.', migrationScriptName)
89
90   const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName))
91
92   return db.sequelize.transaction(t => {
93     const options = {
94       transaction: t,
95       queryInterface: db.sequelize.getQueryInterface(),
96       sequelize: db.sequelize
97     }
98
99     return migrationScript.up(options)
100       .then(() => {
101         // Update the new migration version
102         return db.Application.updateMigrationVersion(versionScript, t)
103       })
104   })
105 }