Skip to content

Commit bfec5ad

Browse files
authored
Merge pull request #545 from AliGebily/feature/export-import-aligebily-1
Topcoder Project Service - Import and Export Data - Final Fixes
2 parents 58f2f60 + 8bb3e23 commit bfec5ad

File tree

17 files changed

+206
-276
lines changed

17 files changed

+206
-276
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
"seed": "babel-node src/tests/seed.js --presets es2015",
2828
"demo-data": "babel-node local/seed",
2929
"es-db-compare": "babel-node scripts/es-db-compare",
30-
"data:export": "babel-node scripts/data/export",
31-
"data:import": "babel-node scripts/data/import"
30+
"data:export": "LOG_LEVEL=info babel-node scripts/data/export",
31+
"data:import": "LOG_LEVEL=info babel-node scripts/data/import"
3232
},
3333
"repository": {
3434
"type": "git",

scripts/data/export/exportData.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { dataModels, validateDataModels } from '../dataModels';
1010
* @return {Promise} Returns a promise
1111
*/
1212
function saveExportedData(filePath, data, logger) {
13-
logger.log('Start Saving data to file....');
13+
logger.info('Start Saving data to file....');
1414
fs.writeFileSync(filePath, JSON.stringify(data));
15-
logger.log('End Saving data to file....');
15+
logger.info('End Saving data to file....');
1616
}
1717
/**
1818
* loads data from database and export it to specified file path
@@ -38,7 +38,7 @@ async function exportDatabaseToJson(filePath, logger) {
3838
const modelName = dataModels[index];
3939
const modelRecords = results[index][0];
4040
allModelsRecords[modelName] = modelRecords;
41-
logger.log(
41+
logger.info(
4242
`Records loaded for model: ${modelName} = ${modelRecords.length}`,
4343
);
4444
}

scripts/data/export/index.js

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
33
import * as readline from 'readline';
4+
import Promise from 'bluebird';
45
import util from '../../../src/util';
56
import { exportData } from './exportData';
67
/**
@@ -12,7 +13,7 @@ import { exportData } from './exportData';
1213
function runExportData(filePath, logger) {
1314
exportData(filePath, logger)
1415
.then(() => {
15-
logger.log('Successfully exported data');
16+
logger.info('Successfully exported data');
1617
process.exit(0);
1718
})
1819
.catch((err) => {
@@ -21,38 +22,39 @@ function runExportData(filePath, logger) {
2122
});
2223
}
2324

24-
setTimeout(() => {
25-
const logger = console;
26-
const filePath =
27-
process.argv[2] === '--file' && process.argv[3]
28-
? process.argv[3]
29-
: 'data/demo-data.json';
30-
logger.log('\nScript will export data to file:', filePath);
31-
// check if file exists
32-
if (fs.existsSync(filePath)) {
33-
const rl = readline.createInterface({
34-
input: process.stdin,
35-
output: process.stdout,
36-
});
37-
// confirm overwritting to file
38-
rl.question(
39-
'File already exists, Are you sure to overwrite it? [Y] to overwrite: ',
40-
(answer) => {
41-
rl.close();
42-
if (answer.toLowerCase() === 'y') {
43-
logger.log('File will be overwritten.');
44-
runExportData(filePath, logger);
45-
} else {
46-
logger.log('Exit without exporting any data');
47-
process.exit(0);
48-
}
49-
},
50-
); // question()
51-
} else {
52-
// get base directory of the file
53-
const baseDir = path.resolve(filePath, '..');
54-
// create directory recursively if it does not exist
55-
util.mkdirSyncRecursive(baseDir);
56-
runExportData(filePath, logger);
57-
}
25+
const logger = util.getAppLogger();
26+
const filePath =
27+
process.argv[2] === '--file' && process.argv[3]
28+
? process.argv[3]
29+
: 'data/demo-data.json';
30+
logger.info('Script will export data to file:', filePath);
31+
// check if file exists
32+
if (fs.existsSync(filePath)) {
33+
// We delay question for overwrite file, because the question overlaps with a warning message from sequelize module
34+
Promise.delay(1).then(() => {
35+
const rl = readline.createInterface({
36+
input: process.stdin,
37+
output: process.stdout,
38+
});
39+
// confirm overwritting to file
40+
rl.question(
41+
'File already exists, Are you sure to overwrite it? [Y] to overwrite: ',
42+
(answer) => {
43+
rl.close();
44+
if (answer.toLowerCase() === 'y') {
45+
logger.info('File will be overwritten.');
46+
runExportData(filePath, logger);
47+
} else {
48+
logger.info('Exit without exporting any data');
49+
process.exit(0);
50+
}
51+
},
52+
); // question()
5853
});
54+
} else {
55+
// get base directory of the file
56+
const baseDir = path.resolve(filePath, '..');
57+
// create directory recursively if it does not exist
58+
util.mkdirSyncRecursive(baseDir);
59+
runExportData(filePath, logger);
60+
}

scripts/data/import/importData.js

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async function writeDataToDatabase(filePath, logger) {
1616
// Start a transaction
1717
transaction = await models.sequelize.transaction();
1818
const jsonData = JSON.parse(fs.readFileSync(filePath).toString());
19+
// we disable no-await-in-loop because we need to run insert operations sequentially to avoid FK constraints errors
1920
/* eslint-disable no-await-in-loop */
2021
for (let index = 0; index < dataModels.length; index += 1) {
2122
const modelName = dataModels[index];
@@ -25,21 +26,21 @@ async function writeDataToDatabase(filePath, logger) {
2526
await models[modelName].bulkCreate(modelRecords, {
2627
transaction,
2728
});
28-
logger.log(
29+
logger.info(
2930
`Records to save for model: ${modelName} = ${modelRecords.length}`,
3031
);
3132
} else {
32-
logger.log(`No records to save for model: ${modelName}`);
33+
logger.info(`No records to save for model: ${modelName}`);
3334
}
3435
}
3536
// commit transaction only if all things went ok
36-
logger.log('committing transaction to database...');
37+
logger.info('committing transaction to database...');
3738
await transaction.commit();
3839
} catch (error) {
3940
logger.error('Error while writing data of model:', currentModelName);
4041
// rollback all insert operations
4142
if (transaction) {
42-
logger.log('rollback database transaction...');
43+
logger.info('rollback database transaction...');
4344
transaction.rollback();
4445
}
4546
if (error.name && error.errors && error.fields) {
@@ -65,10 +66,10 @@ async function writeDataToDatabase(filePath, logger) {
6566
* @return {Promise} Returns a promise
6667
*/
6768
async function indexDataToES(logger) {
68-
logger.log('Indexing metatdata...');
69+
logger.info('Indexing metatdata...');
6970
await indexMetadata();
7071

71-
logger.log('Indexing projects data...');
72+
logger.info('Indexing projects data...');
7273
const req = {
7374
logger,
7475
projectIdStart: 1,
@@ -78,19 +79,7 @@ async function indexDataToES(logger) {
7879
fields: null,
7980
id: 0,
8081
};
81-
await new Promise((resolve, reject) => {
82-
indexProjectsRange(
83-
req,
84-
null,
85-
(error) => {
86-
if (error) {
87-
reject(error);
88-
} else {
89-
resolve();
90-
}
91-
},
92-
);
93-
});
82+
await indexProjectsRange(req);
9483
}
9584

9685
/**

scripts/data/import/index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import * as fs from 'fs';
2+
import util from '../../../src/util';
23
import { importData } from './importData';
34

4-
const logger = console;
5+
const logger = util.getAppLogger();
56
const filePath = (process.argv[2] === '--file' && process.argv[3]) ? process.argv[3] : 'data/demo-data.json';
67
// check if file exists
78
if (!fs.existsSync(filePath)) {
89
logger.error('File is not existing:', filePath);
910
process.exit(1);
1011
} else {
11-
logger.log('Script will import data from file:', filePath);
12+
logger.info('Script will import data from file:', filePath);
1213
importData(filePath, logger)
1314
.then(() => {
14-
logger.log('Successfully imported data');
15+
logger.info('Successfully imported data');
1516
process.exit(0);
1617
})
1718
.catch((err) => {

src/middlewares/performanceRequestLogger.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ module.exports = function logRequest(logger) {
1111
}
1212

1313
// Use the logger with memory usage info
14-
return (request, response, next) => {
15-
const req = request;
16-
const res = response;
14+
return (req, res, next) => {
1715
const startOpts = {
1816
method: req.method,
1917
url: req.url,

src/middlewares/userIdAuth.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ const whitelistedOrigins = JSON.parse(config.get('whitelistedOriginsForUserIdAut
99

1010
/**
1111
* The userId authentication middleware.
12-
* @param {Object} request the request
12+
* @param {Object} req the request
1313
* @param {Object} res the response
1414
* @param {Function} next the next middleware
1515
* @returns {Promise<void>} void
1616
*/
17-
module.exports = function userIdAuth(request, res, next) { // eslint-disable-line consistent-return
18-
const req = request;
17+
module.exports = function userIdAuth(req, res, next) { // eslint-disable-line consistent-return
1918
req.log.debug('Enter userIdAuth middleware');
2019

2120
const bearerUserId = 'Bearer userId_';

src/middlewares/validateMilestoneTemplate.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ const validateMilestoneTemplate = {
4040
* @param {Function} next the express next middleware
4141
*/
4242
// eslint-disable-next-line valid-jsdoc
43-
validateRequestBody: (request, res, next) => {
44-
const req = request;
43+
validateRequestBody: (req, res, next) => {
4544
validateReference(req.body, req)
4645
.then(() => {
4746
if (req.body.sourceReference) {
@@ -110,13 +109,12 @@ const validateMilestoneTemplate = {
110109
* The middleware to validate milestoneTemplateId from request
111110
* path parameter, and set to the request params. This should be called after the validate()
112111
* middleware, and before the permissions() middleware.
113-
* @param {Object} request the express request instance
112+
* @param {Object} req the express request instance
114113
* @param {Object} res the express response instance
115114
* @param {Function} next the express next middleware
116115
*/
117116
// eslint-disable-next-line valid-jsdoc
118-
validateIdParam: (request, res, next) => {
119-
const req = request;
117+
validateIdParam: (req, res, next) => {
120118
models.MilestoneTemplate.findByPk(req.params.milestoneTemplateId)
121119
.then((milestoneTemplate) => {
122120
if (!milestoneTemplate) {

src/middlewares/validateTimeline.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import util from '../util';
77
/**
88
* Common validation code for types of timeline references.
99
* @param {{ reference: string, referenceId: string|number }} sourceObject
10-
* @param {object} request
10+
* @param {object} req
1111
* @param {boolean} [validateProjectExists]
1212
* @returns {Promise}
1313
*/
14-
async function validateReference(sourceObject, request, validateProjectExists) {
15-
const req = request;
14+
async function validateReference(sourceObject, req, validateProjectExists) {
1615
// The source object refers to a project
1716
if (sourceObject.reference === TIMELINE_REFERENCES.PROJECT) {
1817
// Set projectId to the params so it can be used in the permission check middleware
@@ -138,13 +137,12 @@ const validateTimeline = {
138137
* The middleware to validate and get the projectId specified by the timelineId from request
139138
* path parameter, and set to the request params. This should be called after the validate()
140139
* middleware, and before the permissions() middleware.
141-
* @param {Object} request the express request instance
140+
* @param {Object} req the express request instance
142141
* @param {Object} res the express response instance
143142
* @param {Function} next the express next middleware
144143
*/
145144
// eslint-disable-next-line valid-jsdoc
146-
validateTimelineIdParam: (request, res, next) => {
147-
const req = request;
145+
validateTimelineIdParam: (req, res, next) => {
148146
models.Timeline.findByPk(req.params.timelineId)
149147
.then((timeline) => {
150148
if (!timeline) {

src/permissions/connectManagerOrAdmin.ops.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import models from '../models';
66

77
/**
88
* Only Connect Manager, Connect Admin, and administrator are allowed to perform the operations
9-
* @param {Object} request the express request instance
9+
* @param {Object} req the express request instance
1010
* @return {Promise} returns a promise
1111
*/
12-
module.exports = request => new Promise(async (resolve, reject) => {
13-
const req = request;
12+
module.exports = req => new Promise(async (resolve, reject) => {
1413
const hasAccess = util.hasRoles(req, MANAGER_ROLES);
1514

1615
if (!hasAccess) {

0 commit comments

Comments
 (0)