Skip to content

Commit 154c0d0

Browse files
committed
Replace migration mechanism
Old migration mechanism removed due to incompatibility issues. New npm task 'create-migration' added to set up new migrations All existing migrations have been updated to use the new module (and renamed for consistency).
1 parent 0aaa150 commit 154c0d0

16 files changed

Lines changed: 1555 additions & 2264 deletions

conf/migrations.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
migrationsDir: "migrations",
3+
changelogCollectionName: "changelog",
4+
migrationFileExtension: ".js",
5+
useFileHash: false
6+
};

install.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ function start() {
316316
createMasterTenant,
317317
createSuperUser,
318318
buildFrontend,
319-
syncMigrations
319+
installHelpers.runMigrations
320320
], function(error, results) {
321321
if(error) {
322322
console.error('ERROR: ', error);
@@ -517,18 +517,6 @@ function buildFrontend(callback) {
517517
});
518518
}
519519

520-
//As this is a fresh install we dont need to run the migrations so add them to the db and set them to up
521-
function syncMigrations(callback) {
522-
installHelpers.syncMigrations(function(err, migrations) {
523-
database.getDatabase(function(err, db) {
524-
if(err) {
525-
return callback(err);
526-
}
527-
db.update('migration', {}, {'state': 'up'}, callback)
528-
}, masterTenant._id)
529-
});
530-
}
531-
532520
// helper functions
533521

534522
function addConfig(newConfigItems) {

lib/application.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,10 @@ Origin.prototype.startServer = function (options) {
364364
app.router = router(app);
365365
// handle different server states
366366
app.emit(serverOptions.minimal ? "minimalServerStarted" : "serverStarted", app.server);
367-
if(!options.skipStartLog) {
368-
logger.log('info', `Server started listening on port ${port}`);
369-
}
367+
368+
runMigrations().then(() => {
369+
if(!options.skipStartLog) logger.log('info', `Server started listening on port ${port}`);
370+
});
370371
var writeRebuildFile = function(courseFolder, callback) {
371372
var OutputConstants = require('./outputmanager').Constants;
372373
var buildFolder = path.join(courseFolder, OutputConstants.Folders.Build);
@@ -398,6 +399,19 @@ Origin.prototype.startServer = function (options) {
398399
});
399400
};
400401

402+
async function runMigrations() {
403+
try {
404+
const collections = await app.db.conn.db.collections();
405+
if(!collections.find(c => c.collectionName === 'changelog')) {
406+
logger.log('info', 'Need to run migrations. This is a one-time task.');
407+
await installHelpers.runMigrations();
408+
logger.log('info', 'Migrations run successfully');
409+
}
410+
} catch(e) {
411+
logger.log('error', e);
412+
}
413+
}
414+
401415
Origin.prototype.restartServer = function () {
402416
var app = this;
403417
if (app._httpServer) {

lib/installHelpers.js

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ var inquirer = require('inquirer');
99
var logger = require('./logger');
1010
var logUpdate = require('log-update');
1111
var mailer = require('./mailer');
12-
var migrateMongoose = require('migrate-mongoose');
1312
var optimist = require('optimist');
1413
var path = require('path');
1514
var request = require('request');
@@ -71,8 +70,7 @@ var exports = module.exports = {
7170
getInstalledVersions,
7271
getLatestVersions,
7372
getUpdateData,
74-
getMigrationConfig,
75-
syncMigrations,
73+
runMigrations,
7674
installFramework,
7775
updateFramework,
7876
cloneRepo,
@@ -313,38 +311,29 @@ function getFrameworkRoot() {
313311
return path.join(configuration.serverRoot, 'temp', configuration.getConfig('masterTenantID'), 'adapt_framework');
314312
}
315313

316-
function getMigrationConfig(callback) {
317-
var confPath = path.join(configuration.serverRoot, 'conf', 'migrate.json');
318-
fs.readJson(confPath, callback);
314+
async function runMigrations(callback) {
315+
const { config, up } = require('migrate-mongo');
316+
let data;
317+
try {
318+
config.set(require(path.resolve(__dirname, '..', 'conf', 'migrations.js')));
319+
const { db, client } = await getAppDbConnection();
320+
data = await up(db, client);
321+
} catch(e) {
322+
if(callback) return callback(e);
323+
throw e;
324+
}
325+
if(callback) callback(null, data);
326+
return data;
319327
}
320328

321-
/**
322-
* Adds all migrations to the DB in a down state
323-
* @param callback
324-
*/
325-
function syncMigrations(callback) {
326-
getMigrationConfig(function(err, config) {
327-
if(err){
328-
return callback(err)
329+
const getAppDbConnection = () => {
330+
return new Promise(resolve => {
331+
const app = require(path.resolve(__dirname, 'application'))();
332+
if(!!app._httpServer) {
333+
return resolve(app.db.conn);
329334
}
330-
331-
fs.ensureDir(config.migrationsDir, function(err) {
332-
if(err){
333-
return callback(err)
334-
}
335-
336-
var migrator = new migrateMongoose({
337-
migrationsPath: config.migrationsDir,
338-
dbConnectionUri: config.dbConnectionUri,
339-
autosync: true
340-
});
341-
342-
migrator.sync()
343-
.then(
344-
function(value) { return callback(null, value) },
345-
function(reason) { return callback(reason); }
346-
)
347-
});
335+
app.on('serverStarted', () => resolve(app.db.conn));
336+
app.run({ skipVersionCheck: true, skipDependencyCheck: true });
348337
});
349338
}
350339

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Removes all old sessions from the database
3+
*/
4+
module.exports = {
5+
async up(db, client) {
6+
try {
7+
await db.dropCollection('sessions');
8+
} catch(e) {}
9+
},
10+
async down(db, client) {}
11+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* The following roles have been removed: Product Manager, Course Creator
3+
* Any existing users with these roles will be mapped to Tenant Admin and Super Admin respectively.
4+
*/
5+
module.exports = {
6+
async up(db, client) {
7+
const roles = db.collection('roles');
8+
const users = db.collection('users');
9+
const replacements = [
10+
['Product Manager', 'Course Creator'],
11+
['Tenant Admin', 'Super Admin']
12+
];
13+
await Promise.all(replacements.map(async ([oldName, newName]) => {
14+
const [oldRole, newRole] = await Promise.all([ roles.find({ name: oldName }), roles.find({ name: newName }) ]);
15+
if(!oldRole) {
16+
return;
17+
}
18+
if(!newRole) {
19+
throw new Error(`Db must define the ${newRole} to replace ${oldRole}`);
20+
}
21+
await users.updateMany({ roles: { $in: [oldRole._id] } }, { $set: { roles: [newRole._id] } });
22+
await roles.deleteOne({ name: oldName });
23+
}));
24+
},
25+
26+
async down(db, client) {}
27+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const origin = require('../lib/application');
2+
/**
3+
* Converts all config._ariaLevels properties to new number format
4+
* Removes any content items which use the _ariaLevel override default value of 0 (any non-zero values are left)
5+
*/
6+
module.exports = {
7+
async up(db, client) {
8+
const collection = db.collection('configs');
9+
const oldDefaults = {
10+
_menu: 1,
11+
_menuGroup: 2,
12+
_menuItem: 2,
13+
_page: 1,
14+
_article: 2,
15+
_block: 3,
16+
_component: 4,
17+
_componentItem: 5,
18+
_notify: 1,
19+
};
20+
const props = origin().db.getModel('config')?.schema?.tree?._accessibility?._ariaLevels?.properties;
21+
if(!props) {
22+
throw new Error(`Couldn't parse ARIA level defaults`);
23+
}
24+
const newDefaults = Object.entries(props).reduce((m, [k, v]) => Object.assign(m, { [k]: v.default }), {});
25+
const configs = await (collection.find().toArray());
26+
27+
await Promise.all(configs.map(async c => {
28+
if(!c?._accessibility?._ariaLevels) {
29+
return;
30+
}
31+
const levels = c._accessibility._ariaLevels;
32+
Object.entries(levels).forEach(([k, v]) => levels[k] = (v === oldDefaults[k]) ? newDefaults[k] : v.toString());
33+
return collection.updateOne({ _id: c._id }, { $set: c });
34+
}));
35+
36+
await Promise.all(['contentobjects', 'articles', 'blocks', 'components'].map(c => {
37+
const collection = db.collection(c);
38+
return collection.updateMany({ _ariaLevel: 0 }, { $set: { _ariaLevel: "" } });
39+
}));
40+
},
41+
42+
async down(db, client) {}
43+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Removes the deprecated migrations database collection
3+
*/
4+
module.exports = {
5+
async up(db, client) {
6+
try {
7+
await db.dropCollection('migrations');
8+
} catch(e) {}
9+
},
10+
async down(db, client) {}
11+
};

migrations/helpers/helper.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

migrations/helpers/template.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)