Skip to content

Commit 1cc7bc1

Browse files
authored
Merge pull request #520 from topcoder-platform/feature/link-attachments
Links as Attachments + Tags - Migration Scripts Optimisations
2 parents 0fd0599 + 6846d5f commit 1cc7bc1

File tree

2 files changed

+83
-27
lines changed

2 files changed

+83
-27
lines changed

migrations/bookmarks/migrateBookmarksToLinks.js

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import _ from 'lodash';
7+
import sequelize from 'sequelize';
78
import models from '../../src/models';
89
import { ATTACHMENT_TYPES } from '../../src/constants';
910

@@ -14,20 +15,41 @@ console.log('Migrate project.bookmarks to project.attachments for all projects i
1415
*
1516
* @returns {Promise} the DB data
1617
*/
17-
const getAllProjectsFromDB = () => models.Project.findAll({ raw: false });
18+
const getProjectsWithBookmarks = () => models.Project.findAll({
19+
raw: false,
20+
attributes: ['id', 'bookmarks'],
21+
where: sequelize.where(
22+
sequelize.fn('json_array_length', sequelize.col('bookmarks')),
23+
{ [sequelize.Op.gt]: 0 },
24+
),
25+
});
1826

1927
/**
2028
* Executes the bookmarks migration to link attachments
2129
* @returns {Promise} resolved when migration is complete
2230
*/
2331
const migrateBookmarks = async () => {
24-
const projects = await getAllProjectsFromDB();
32+
const projects = await getProjectsWithBookmarks();
33+
let count = 0;
34+
35+
console.log(`Found ${projects.length} projects.`);
2536

2637
for (const project of projects) {
27-
const bookmarks = _.get(project, 'bookmarks');
38+
await models.sequelize.transaction(async (tr) => { // eslint-disable-line no-loop-func
39+
count += 1;
40+
const percentage = Math.round((count / projects.length) * 100);
41+
42+
console.log(`Processing project id ${project.id}: ${count}/${projects.length} (${percentage}%)...`);
43+
44+
const bookmarks = _.get(project, 'bookmarks', []);
45+
console.log(`Processing project id ${project.id}: found ${bookmarks.length} bookmarks`);
2846

29-
_.each(bookmarks, async (b) => {
30-
await models.ProjectAttachment.create({
47+
if (bookmarks.length === 0) {
48+
console.log(`Processing project id ${project.id}: skipped.`);
49+
return;
50+
}
51+
52+
const attachments = bookmarks.map(b => ({
3153
projectId: project.id,
3254
type: ATTACHMENT_TYPES.LINK,
3355
title: b.title,
@@ -37,17 +59,25 @@ const migrateBookmarks = async () => {
3759
updatedAt: _.isNil(b.updatedAt) ? project.updatedAt : b.updatedAt,
3860
updatedBy: _.isNil(b.updatedBy) ? project.updatedBy : b.updatedBy,
3961
tags: [],
40-
});
62+
}));
63+
64+
await models.ProjectAttachment.bulkCreate(attachments, { transaction: tr });
65+
console.log(`Processing project id ${project.id}: attachments created.`);
66+
67+
project.bookmarks = [];
68+
await project.save({ transaction: tr });
69+
console.log(`Processing project id ${project.id}: bookmarks removed.`);
70+
71+
console.log(`Processing project id ${project.id}: done.`);
4172
});
42-
project.bookmarks = [];
43-
await project.save();
4473
}
4574
};
4675

4776
migrateBookmarks().then(() => {
4877
console.log('Migration of projects bookmarks to project links attachments finished!');
4978
process.exit();
5079
}).catch((e) => {
51-
console.log(e);
80+
console.error('Migration of projects bookmarks to project links attachments failed!');
81+
console.error(e);
5282
process.exit();
5383
});

migrations/bookmarks/migrateLinksToBookmarks.js

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ console.log('Migrate project.attachments of type \'link\' to project.bookmarks f
1414
*
1515
* @returns {Promise} the DB data
1616
*/
17-
const getAllProjectsFromDB = async () => models.Project.findAll({ raw: false });
17+
const getAllProjectsFromDB = async () => models.Project.findAll({
18+
raw: false,
19+
attributes: ['id', 'bookmarks'],
20+
});
1821

1922
/**
2023
* Gets the active project links (Links that were not deleted) for the given project.
@@ -23,49 +26,72 @@ const getAllProjectsFromDB = async () => models.Project.findAll({ raw: false });
2326
* @returns {Promise} The active project links promise
2427
*/
2528
const getActiveProjectLinks = async projectId => models.ProjectAttachment
26-
.findAll({
27-
where: {
28-
projectId,
29-
deletedAt: { $eq: null },
30-
type: ATTACHMENT_TYPES.LINK,
31-
},
32-
raw: false,
33-
});
29+
.findAll({
30+
where: {
31+
projectId,
32+
type: ATTACHMENT_TYPES.LINK,
33+
},
34+
raw: true,
35+
});
3436

3537
/**
3638
* Executes the migration of link attachments to bookmarks for all projects in the database.
3739
* @returns {Promise} resolved when the migration is complete
3840
*/
3941
const migrateLinksToBookmarks = async () => {
4042
const projects = await getAllProjectsFromDB();
43+
let count = 0;
44+
45+
console.log(`Found ${projects.length} projects in total.`);
4146

4247
for (const project of projects) {
43-
// get the project links
44-
const links = await getActiveProjectLinks(project.id);
45-
const bookmarks = [];
48+
await models.sequelize.transaction(async (tr) => { // eslint-disable-line no-loop-func
49+
count += 1;
50+
const percentage = Math.round((count / projects.length) * 100);
51+
52+
console.log(`Processing project id ${project.id}: ${count}/${projects.length} (${percentage}%)...`);
53+
54+
const links = await getActiveProjectLinks(project.id);
55+
console.log(`Processing project id ${project.id}: found ${links.length} link attachments`);
56+
57+
if (links.length === 0) {
58+
console.log(`Processing project id ${project.id}: skipped.`);
59+
return;
60+
}
4661

47-
_.each(links, async (link) => {
48-
bookmarks.push({
62+
const bookmarks = links.map(link => ({
4963
title: link.title,
5064
address: link.path,
5165
createdAt: link.createdAt,
5266
createdBy: link.createdBy,
5367
updatedAt: link.updatedAt,
5468
updatedBy: link.updatedBy,
69+
}));
70+
71+
project.bookmarks = bookmarks;
72+
await project.save({
73+
transaction: tr,
5574
});
75+
console.log(`Processing project id ${project.id}: bookmarks created.`);
5676

57-
await link.destroy();
58-
});
77+
await models.ProjectAttachment.destroy({
78+
where: {
79+
id: _.map(links, 'id'),
80+
},
81+
transaction: tr,
82+
});
83+
console.log(`Processing project id ${project.id}: attachments removed.`);
5984

60-
project.bookmarks = bookmarks;
61-
await project.save();
85+
console.log(`Processing project id ${project.id}: done.`);
86+
});
6287
}
6388
};
6489

6590
migrateLinksToBookmarks().then(() => {
6691
console.log('Migration of projects link attachments to project bookmarks finished!');
6792
process.exit();
6893
}).catch((e) => {
94+
console.error('Migration of projects link attachments to project bookmarks failed!');
6995
console.log(e);
7096
process.exit();
7197
});

0 commit comments

Comments
 (0)