Skip to content

Commit

Permalink
Merge branch 'master' into LL-295
Browse files Browse the repository at this point in the history
  • Loading branch information
ryasmi authored Mar 20, 2020
2 parents bf46b19 + 334935f commit 651e3bf
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 11 deletions.
42 changes: 36 additions & 6 deletions cli/src/migrateMongo/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import logger from 'lib/logger';
import migration from 'cli/migrateMongo/models/migration';
import { isBoolean, isString, map } from 'lodash';
import { isBoolean, isString, map, find } from 'lodash';
import v2Migrations from 'cli/commands/v2-migrations';
import { OrderedMap, List } from 'immutable';
import { map as bmap } from 'bluebird';
import migrate from './migrate';

const getOutstandingMigrations = async ({ down, up, migrations }) => {
const lastMigration = await migration.findOne({}).sort({ updatedAt: -1 });
const lastMigration = await migration.findOne({}).sort({ order: -1, updatedAt: -1 });

const lastKey = lastMigration ? lastMigration.key : null;
if (down) {
Expand Down Expand Up @@ -80,8 +81,35 @@ const getOutstandingMigrations = async ({ down, up, migrations }) => {
return outstandingMigrations;
};

export const fixDbMigrationOrder = async ({ migrations }) => {
const dbMigrations = await migration.find({}).sort({ order: 1 });
let toSave = [];

let inc = 1;
for (const migrationItem of migrations.keySeq().toJS()) {
// eslint-disable-next-line no-loop-func
const dbMigration = find(
dbMigrations,
dbMigrationItem => migrationItem === dbMigrationItem.key
);
if (!dbMigration) {
break;
}

dbMigration.order = inc;
toSave = [dbMigration, ...toSave];

inc += 1;
}

await bmap(toSave, (toSav) => {
const out = toSav.save();
return out;
});
};

const checkRunMigrations = async ({ migrations }) => {
const dbMigrations = new List(await migration.find({}));
const dbMigrations = new List(await migration.find({}).sort({ order: 1 }));
const actualMigrations = new List(migrations);
const allMigrations = dbMigrations.zip(actualMigrations);

Expand Down Expand Up @@ -138,15 +166,15 @@ const displayInfo = async ({ info, migrations }) => {
const verbose = info === 'v' || info === 'verbose';

if (!verbose) {
const lastRunMigration = await migration.findOne().sort({ updatedAt: -1 });
const lastRunMigration = await migration.findOne().sort({ order: -1, updatedAt: -1 });

if (!lastRunMigration) {
logger.info('No migrations have been run');
} else {
logger.info('Last run migration: ', lastRunMigration.key);
}
} else {
const runMigrations = await migration.find().sort({ updatedAt: 1 });
const runMigrations = await migration.find().sort({ order: 1, updatedAt: 1 });

const output = map(runMigrations, item => item.key);

Expand All @@ -170,10 +198,12 @@ const displayInfo = async ({ info, migrations }) => {
}
};

export default async function ({ down, up, info, migrations = v2Migrations, dontExit = false }, next = null) {
export default async function ({ down, up, info, migrations = v2Migrations, dontExit = false, fixOrder = false }, next = null) {
try {
if (info) {
await displayInfo({ info, migrations });
} else if (fixOrder) {
await fixDbMigrationOrder({ migrations });
} else {
await doMigrations({ down, up, migrations });
}
Expand Down
9 changes: 6 additions & 3 deletions cli/src/migrateMongo/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const downFn = async ({ key, down }) => {
logger.info(`Finished down migration of ${key}`);
};

const migrateOne = async ({ migrationKey, migration, down: doDown }) => {
const migrateOne = async ({ migrationKey, migration, down: doDown, order }) => {
const { up, down } = migration;

if (doDown) {
Expand All @@ -29,11 +29,13 @@ const migrateOne = async ({ migrationKey, migration, down: doDown }) => {
logger.info(`Starting up migration of ${migrationKey}`);
await up();

await new Migration({
const out = await new Migration({
key: migrationKey,
upFn: up.toString()
upFn: up.toString(),
order
}).save();
logger.info(`Finished up migration of ${migrationKey}`);
return out;
} catch (err) {
logger.error(`Error migrating up ${migrationKey}, Reverting ${migrationKey}`);
await downFn({
Expand All @@ -54,6 +56,7 @@ const migrate = async ({ migrations, down }) => {
return migrateOne({
migrationKey: key,
migration: value,
order: (acc || { order: 0 }).order + 1,
down
});
},
Expand Down
80 changes: 80 additions & 0 deletions cli/src/migrateMongo/migrateMongo-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,84 @@ describe('migrateMongo', () => {
await expect(result).to.eventually.be.rejectedWith(Error);
});
});
describe('fix order', () => {
it('should set the order', async () => {
await promisify(migrator)({
migrations,
dontExit: true
});

const dbRunMigrations = await migration.find({
key: { $in: ['001-test', '002-test'] }
});
expect(dbRunMigrations.length).to.equal(2);
expect(dbRunMigrations[0].order).to.equal(1);
expect(dbRunMigrations[1].order).to.equal(2);
});

it('should reorder', async () => {
await promisify(migrator)({
migrations,
dontExit: true
});

const dbRunMigrations = await migration.find({
key: { $in: ['001-test', '002-test'] }
});
dbRunMigrations[0].order = 2;
await dbRunMigrations[0].save();

dbRunMigrations[1].order = 1;
await dbRunMigrations[1].save();

await promisify(migrator)({
migrations,
dontExit: true,
fixOrder: true
});

const dbRunMigrations2 = await migration.find({
key: { $in: ['001-test', '002-test'] }
});

expect(dbRunMigrations2[0].order).to.equal(1);
expect(dbRunMigrations2[1].order).to.equal(2);

let errored = false;
try {
await promisify(migrator)({
migrations,
dontExit: true,
});
} catch (err) {
errored = true;
}
expect(errored).to.equal(false);
});

it('should migrate if first items have no order', async () => {
await promisify(migrator)({
migrations,
dontExit: true
});

const dbRunMigrations = await migration.find({
key: { $in: ['001-test', '002-test'] }
});
dbRunMigrations[0].order = null;
await dbRunMigrations[0].save();

await promisify(migrator)({
migrations,
dontExit: true
});

const dbRunMigrations2 = await migration.find({
key: { $in: ['001-test', '002-test'] }
});

expect(dbRunMigrations2[0].order).to.equal(null);
expect(dbRunMigrations2[1].order).to.equal(2);
});
});
});
3 changes: 2 additions & 1 deletion cli/src/migrateMongo/models/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { getConnection } from 'lib/connections/mongoose';

const schema = new mongoose.Schema({
key: String,
upFn: String
upFn: String,
order: Number
});

schema.plugin(timestamps);
Expand Down
3 changes: 2 additions & 1 deletion cli/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ program
'-d, --down <down>',
"Optional, runs down migration down to [down file name], also accepts ['last']"
)
.option('-i, --info [info]', "Display the state of the migrations, optional ['v'|'verbose']");
.option('-i, --info [info]', "Display the state of the migrations, optional ['v'|'verbose']")
.option('-f, --fixOrder [fixOrder]', 'Resolves the migration order conflicts');
// node cli/dist/server migrateMongo

program
Expand Down

0 comments on commit 651e3bf

Please sign in to comment.