aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers/migrator.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/initializers/migrator.ts')
-rw-r--r--server/initializers/migrator.ts133
1 files changed, 52 insertions, 81 deletions
diff --git a/server/initializers/migrator.ts b/server/initializers/migrator.ts
index d8faaebc6..d381551b5 100644
--- a/server/initializers/migrator.ts
+++ b/server/initializers/migrator.ts
@@ -1,70 +1,54 @@
1import { waterfall, eachSeries } from 'async'
2import * as fs from 'fs'
3import * as path from 'path' 1import * as path from 'path'
4import * as Sequelize from 'sequelize' 2import * as Promise from 'bluebird'
5 3
6import { database as db } from './database' 4import { database as db } from './database'
7import { LAST_MIGRATION_VERSION } from './constants' 5import { LAST_MIGRATION_VERSION } from './constants'
8import { logger } from '../helpers' 6import { logger, readdirPromise } from '../helpers'
9 7
10function migrate (finalCallback: (err: Error) => void) { 8function migrate () {
11 waterfall([ 9 const p = db.sequelize.getQueryInterface().showAllTables()
12 10 .then(tables => {
13 function checkApplicationTableExists (callback) { 11 // No tables, we don't need to migrate anything
14 db.sequelize.getQueryInterface().showAllTables().asCallback(function (err, tables) { 12 // The installer will do that
15 if (err) return callback(err) 13 if (tables.length === 0) throw null
16 14 })
17 // No tables, we don't need to migrate anything 15 .then(() => {
18 // The installer will do that 16 return db.Application.loadMigrationVersion()
19 if (tables.length === 0) return finalCallback(null) 17 })
20 18 .then(actualVersion => {
21 return callback(null)
22 })
23 },
24
25 function loadMigrationVersion (callback) {
26 db.Application.loadMigrationVersion(callback)
27 },
28
29 function createMigrationRowIfNotExists (actualVersion, callback) {
30 if (actualVersion === null) { 19 if (actualVersion === null) {
31 db.Application.create({ 20 return db.Application.create({ migrationVersion: 0 }).then(() => 0)
32 migrationVersion: 0
33 }, function (err) {
34 return callback(err, 0)
35 })
36 } 21 }
37 22
38 return callback(null, actualVersion) 23 return actualVersion
39 }, 24 })
40 25 .then(actualVersion => {
41 function abortMigrationIfNotNeeded (actualVersion, callback) { 26 // No need migrations, abort
42 // No need migrations 27 if (actualVersion >= LAST_MIGRATION_VERSION) throw null
43 if (actualVersion >= LAST_MIGRATION_VERSION) return finalCallback(null)
44
45 return callback(null, actualVersion)
46 },
47 28
48 function getMigrations (actualVersion, callback) { 29 return actualVersion
30 })
31 .then(actualVersion => {
49 // If there are a new migration scripts 32 // If there are a new migration scripts
50 logger.info('Begin migrations.') 33 logger.info('Begin migrations.')
51 34
52 getMigrationScripts(function (err, migrationScripts) { 35 return getMigrationScripts().then(migrationScripts => ({ actualVersion, migrationScripts }))
53 return callback(err, actualVersion, migrationScripts) 36 })
37 .then(({ actualVersion, migrationScripts }) => {
38 return Promise.mapSeries(migrationScripts, entity => {
39 return executeMigration(actualVersion, entity)
54 }) 40 })
55 }, 41 })
42 .then(() => {
43 logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
44 })
45 .catch(err => {
46 if (err === null) return undefined
56 47
57 function doMigrations (actualVersion, migrationScripts, callback) { 48 throw err
58 eachSeries(migrationScripts, function (entity: any, callbackEach) { 49 })
59 executeMigration(actualVersion, entity, callbackEach)
60 }, function (err) {
61 if (err) return callback(err)
62 50
63 logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION) 51 return p
64 return callback(null)
65 })
66 }
67 ], finalCallback)
68} 52}
69 53
70// --------------------------------------------------------------------------- 54// ---------------------------------------------------------------------------
@@ -75,12 +59,12 @@ export {
75 59
76// --------------------------------------------------------------------------- 60// ---------------------------------------------------------------------------
77 61
78type GetMigrationScriptsCallback = (err: Error, filesToMigrate?: { version: string, script: string }[]) => void 62function getMigrationScripts () {
79function getMigrationScripts (callback: GetMigrationScriptsCallback) { 63 return readdirPromise(path.join(__dirname, 'migrations')).then(files => {
80 fs.readdir(path.join(__dirname, 'migrations'), function (err, files) { 64 const filesToMigrate: {
81 if (err) return callback(err) 65 version: string,
82 66 script: string
83 const filesToMigrate = [] 67 }[] = []
84 68
85 files.forEach(function (file) { 69 files.forEach(function (file) {
86 // Filename is something like 'version-blabla.js' 70 // Filename is something like 'version-blabla.js'
@@ -91,15 +75,15 @@ function getMigrationScripts (callback: GetMigrationScriptsCallback) {
91 }) 75 })
92 }) 76 })
93 77
94 return callback(err, filesToMigrate) 78 return filesToMigrate
95 }) 79 })
96} 80}
97 81
98function executeMigration (actualVersion: number, entity: { version: string, script: string }, callback: (err: Error) => void) { 82function executeMigration (actualVersion: number, entity: { version: string, script: string }) {
99 const versionScript = parseInt(entity.version, 10) 83 const versionScript = parseInt(entity.version, 10)
100 84
101 // Do not execute old migration scripts 85 // Do not execute old migration scripts
102 if (versionScript <= actualVersion) return callback(null) 86 if (versionScript <= actualVersion) return undefined
103 87
104 // Load the migration module and run it 88 // Load the migration module and run it
105 const migrationScriptName = entity.script 89 const migrationScriptName = entity.script
@@ -107,30 +91,17 @@ function executeMigration (actualVersion: number, entity: { version: string, scr
107 91
108 const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName)) 92 const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName))
109 93
110 db.sequelize.transaction().asCallback(function (err, t) { 94 return db.sequelize.transaction(t => {
111 if (err) return callback(err)
112
113 const options = { 95 const options = {
114 transaction: t, 96 transaction: t,
115 queryInterface: db.sequelize.getQueryInterface(), 97 queryInterface: db.sequelize.getQueryInterface(),
116 sequelize: db.sequelize, 98 sequelize: db.sequelize
117 Sequelize: Sequelize
118 } 99 }
119 migrationScript.up(options, function (err) {
120 if (err) {
121 t.rollback()
122 return callback(err)
123 }
124
125 // Update the new migration version
126 db.Application.updateMigrationVersion(versionScript, t, function (err) {
127 if (err) {
128 t.rollback()
129 return callback(err)
130 }
131 100
132 t.commit().asCallback(callback) 101 migrationScript.up(options)
102 .then(() => {
103 // Update the new migration version
104 db.Application.updateMigrationVersion(versionScript, t)
133 }) 105 })
134 })
135 }) 106 })
136} 107}