Fix request schedulers stats
[oweals/peertube.git] / server / initializers / migrator.js
1 'use strict'
2
3 const waterfall = require('async/waterfall')
4 const eachSeries = require('async/eachSeries')
5 const fs = require('fs')
6 const path = require('path')
7
8 const constants = require('./constants')
9 const db = require('./database')
10 const logger = require('../helpers/logger')
11
12 const migrator = {
13   migrate: migrate
14 }
15
16 function migrate (finalCallback) {
17   waterfall([
18
19     function checkApplicationTableExists (callback) {
20       db.sequelize.getQueryInterface().showAllTables().asCallback(function (err, tables) {
21         if (err) return callback(err)
22
23         // No tables, we don't need to migrate anything
24         // The installer will do that
25         if (tables.length === 0) return finalCallback(null)
26
27         return callback(null)
28       })
29     },
30
31     function loadMigrationVersion (callback) {
32       db.Application.loadMigrationVersion(callback)
33     },
34
35     function abortMigrationIfNotNeeded (actualVersion, callback) {
36       // No need migrations
37       if (actualVersion >= constants.LAST_MIGRATION_VERSION) return finalCallback(null)
38
39       return callback(null, actualVersion)
40     },
41
42     function getMigrations (actualVersion, callback) {
43       // If there are a new migration scripts
44       logger.info('Begin migrations.')
45
46       getMigrationScripts(function (err, migrationScripts) {
47         return callback(err, actualVersion, migrationScripts)
48       })
49     },
50
51     function doMigrations (actualVersion, migrationScripts, callback) {
52       eachSeries(migrationScripts, function (entity, callbackEach) {
53         executeMigration(actualVersion, entity, callbackEach)
54       }, function (err) {
55         if (err) return callback(err)
56
57         logger.info('Migrations finished. New migration version schema: %s', constants.LAST_MIGRATION_VERSION)
58         return callback(null)
59       })
60     }
61   ], finalCallback)
62 }
63
64 // ---------------------------------------------------------------------------
65
66 module.exports = migrator
67
68 // ---------------------------------------------------------------------------
69
70 function getMigrationScripts (callback) {
71   fs.readdir(path.join(__dirname, 'migrations'), function (err, files) {
72     if (err) return callback(err)
73
74     const filesToMigrate = []
75
76     files.forEach(function (file) {
77       // Filename is something like 'version-blabla.js'
78       const version = file.split('-')[0]
79       filesToMigrate.push({
80         version,
81         script: file
82       })
83     })
84
85     return callback(err, filesToMigrate)
86   })
87 }
88
89 function executeMigration (actualVersion, entity, callback) {
90   const versionScript = parseInt(entity.version)
91
92   // Do not execute old migration scripts
93   if (versionScript <= actualVersion) return callback(null)
94
95   // Load the migration module and run it
96   const migrationScriptName = entity.script
97   logger.info('Executing %s migration script.', migrationScriptName)
98
99   const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName))
100
101   db.sequelize.transaction().asCallback(function (err, t) {
102     if (err) return callback(err)
103
104     const options = {
105       transaction: t,
106       queryInterface: db.sequelize.getQueryInterface(),
107       sequelize: db.sequelize,
108       Sequelize: db.Sequelize
109     }
110     migrationScript.up(options, function (err) {
111       if (err) {
112         t.rollback()
113         return callback(err)
114       }
115
116       // Update the new migration version
117       db.Application.updateMigrationVersion(versionScript, t, function (err) {
118         if (err) {
119           t.rollback()
120           return callback(err)
121         }
122
123         t.commit().asCallback(callback)
124       })
125     })
126   })
127 }