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