Skip to content
This repository has been archived by the owner on Mar 29, 2019. It is now read-only.

Bulk tables 性能优化 查询优化 #119

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions app/constants/codes.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ const ECodes = {
code: 'BULK_COPY_PARAMS_ERROR',
message: 'SourceColumnConfigs and sourceCellValues2dArray must be array.',
},
ORIGINAL_POSITIONS_MISSING: {
code: 'ORIGINAL_POSITIONS_MISSING',
message: 'OriginalPositions can not be empty.',
UNSUPPORTED_POSITION_TYPE: {
code: 'UNSUPPORTED_POSITION_TYPE',
message: 'Unsupported position type.',
},
ILLEGAL_TARGET_POSITION: {
code: 'ILLEGAL_TARGET_POSITION',
message: 'Illegal targetPosition.',
ILLEGAL_POSITION: {
code: 'ILLEGAL_POSITION',
message: 'Illegal position.',
},
USER_NOT_FOUND: {
code: 'USER_NOT_FOUND',
Expand Down
39 changes: 9 additions & 30 deletions app/controllers/positions.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
const posQueries = require('../queries/positions');
const { POSITION_TYPE } = require('../constants/app');
const { error, Status, ECodes } = require('../util/error');

module.exports = {
changePosition({ originalPositions, targetPosition, parentId, type }) {
targetPosition = parseInt(targetPosition);
originalPositions = Array.from(originalPositions, i => parseInt(i));
originalPositions.sort();
const originLen = originalPositions.length;
const minPosition = Math.min(originalPositions[0], targetPosition);
const maxPosition = Math.max(
originalPositions[originLen - 1],
targetPosition,
);
const temp = originalPositions.reduce((sum, originalPosition) => {
if (originalPosition < targetPosition) sum++;
return sum;
}, 0);
let movedNum = 0;
let sql = `update positions set position = case`;
for (let i = minPosition; i <= maxPosition; i++) {
if (originalPositions.indexOf(i) === -1) {
if (i >= targetPosition) {
sql += ` when position = ${i} then ${i + originLen - movedNum}`;
} else {
sql += ` when position = ${i} then ${i - movedNum}`;
}
} else {
sql += ` when position = ${i} then ${targetPosition - temp + movedNum}`;
movedNum++;
}
}
sql += ` else position end where "parentId" = ? and "type" = ?`;
return posQueries.query(sql, { replacements: [parentId, type] });
changePosition(params) {
if (
params.type === POSITION_TYPE.FIELD &&
(params.targetPosition === 1 || params.originalPosition === 1)
)
error(Status.Forbidden, ECodes.ILLEGAL_POSITION);
return posQueries.updateOne(params);
},

async create({ siblingId, parentId, type }) {
Expand Down
23 changes: 7 additions & 16 deletions app/controllers/tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const fldController = require('../controllers/fields');
const fldValController = require('../controllers/fieldValues');
const { POSITION_TYPE } = require('../constants/app');
const { error, Status, ECodes } = require('../util/error');
const { checkKeyExists, trim } = require('../util/helper');
const { checkKeyExists, trim, getUniqueName } = require('../util/helper');
const { checkType } = require('../util/fieldTypes');

const checkTable = async id => {
Expand All @@ -22,16 +22,6 @@ const checkNameWithinBase = async (baseId, name) => {
if (table) error(Status.Forbidden, ECodes.TABLE_NAME_EXIST, name);
};

const getUniqueTableName = async (baseId, tableName, index = 0) => {
let newTableName = index ? `${tableName} (${index})` : tableName;
const table = await tblQueries.getTableByBaseAndName(baseId, newTableName);
if (table) {
index++;
return await getUniqueTableName(baseId, tableName, index);
}
return newTableName;
};

module.exports = {
checkTable,
async createNewTableSet(params) {
Expand Down Expand Up @@ -116,11 +106,13 @@ module.exports = {
let tblFvFlag = [];
let tblFldFlag = [];
let tableSchemas = [];
const tableNamesResult = await tblQueries.getTableNames(baseId);
const tableNames = tableNamesResult.map(i => i.name.toLowerCase());
for (const table of tables) {
checkKeyExists(table, 'name', 'fields');
table.name = trim(table.name);
if (table.name === '') error(null, ECodes.TABLE_NAME_EMPTY);
table.name = await getUniqueTableName(baseId, table.name);
table.name = getUniqueName(tableNames, table.name);
tblRecords.push({ baseId, name: table.name });
const tableNum = tblRecords.length;
fldRecords[tableNum - 1] = [];
Expand All @@ -129,16 +121,19 @@ module.exports = {
let tblFvNum = 0;
let index = 0;
let tableSchema = { name: table.name, id: null, columns: [] };
let fieldNames = [];
for (const field of table.fields) {
let tblRows = 0;
checkKeyExists(field, 'name', 'type', 'typeOptions', 'values');
field.name = trim(field.name);
if (field.name === '') field.name = 'Unknown Field ' + ++index;
field.name = getUniqueName(fieldNames, field.name);
fldRecords[tableNum - 1].push({
name: field.name,
fieldTypeId: await checkType(field.type),
typeOptions: field.typeOptions,
});
fieldNames.push(field.name.toLowerCase());
const fvLen = field.values.length;
tblFvNum += fvLen;
if (fvLen > tblMaxRows) {
Expand Down Expand Up @@ -194,10 +189,6 @@ module.exports = {
tableSchemas[i].id = tblResults[i].id;
for (let j = 0; j < fldRecords[i].length; j++) {
fldRecords[i][j].tableId = tblResults[i].id;
await fldController.checkFieldByTableAndName(
tblResults[i].id,
fldRecords[i][j].name,
);
fldPosRecords.push({
parentId: tblResults[i].id,
siblingId: null,
Expand Down
16 changes: 16 additions & 0 deletions app/queries/positions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
sequelize,
} = require('../models');
const { POSITION_TYPE } = require('../constants/app');
const { error, Status, ECodes } = require('../util/error');

const POSITION_MODELS = {
[POSITION_TYPE.BASE]: BasePositions,
Expand Down Expand Up @@ -42,4 +43,19 @@ module.exports = {
const PosModel = POSITION_MODELS[type];
return PosModel.bulkCreate(records);
},

updateOne(params) {
const tableName =
params.type.slice(0, 1).toUpperCase() +
params.type.slice(1) +
'Positions';
const sql = `update "${tableName}" set "position" = case when "position"=${
params.originalPosition
} then ${params.targetPosition} when "position"=${
params.targetPosition
} then ${params.originalPosition} else "position" end where "parentId"='${
params.parentId
}'`;
return sequelize.query(sql);
},
};
7 changes: 7 additions & 0 deletions app/queries/tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,11 @@ module.exports = {
bulkCreate(records) {
return Tables.bulkCreate(records);
},

getTableNames(baseId) {
return Tables.findAll({
attributes: ['name'],
where: { baseId },
});
},
};
16 changes: 8 additions & 8 deletions app/resolvers/positions.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
const { checkKeyExists } = require('../util/helper');
const posController = require('../controllers/positions');
const socketIo = require('../../lib/socketIo');
const { error, Status, ECodes } = require('../util/error');
const { sequelize } = require('../models/index');
const { POSITION_TYPE } = require('../constants/app');

const changePosition = async ctx => {
const params = ctx.request.body;
checkKeyExists(
params,
'originalPositions',
'originalPosition',
'targetPosition',
'parentId',
'type',
);
if (params.originalPositions.length === 0)
error(null, ECodes.ORIGINAL_POSITIONS_MISSING);
if (!(params.targetPosition > 1)) error(null, ECodes.ILLEGAL_TARGET_POSITION);
if (!Array.isArray(params.originalPositions))
params.originalPositions = [params.originalPositions];
await posController.changePosition(params);
params.originalPosition = parseInt(params.originalPosition);
params.targetPosition = parseInt(params.targetPosition);
if (!(params.originalPosition > 0) || !(params.targetPosition > 0))
error(Status.Forbidden, ECodes.ILLEGAL_POSITION);
await sequelize.transaction(() => posController.changePosition(params));
ctx.body = { message: 'success' };
socketIo.sync({
op: 'changePosition',
Expand Down
4 changes: 2 additions & 2 deletions app/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ router.delete('/api/array-field-item', fldValResolver.deleteArrayValue);
// TODO fix bulk copy
// router.post('/api/bulk-copy-field-value', resolveBulkCopyFieldValue);

// //Position
// router.put('/api/change-position', posResolver.changePosition);
//Position
router.put('/api/change-position', posResolver.changePosition);

//FieldTypes
router.get('/api/fieldTypes', fldTypesResolver.getAll);
Expand Down
10 changes: 10 additions & 0 deletions app/util/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,19 @@ const trim = str => {
return str.toString().replace(/(^\s*)|(\s*$)/g, '');
};

const getUniqueName = (names, name, index = 0) => {
let newName = index ? `${name} (${index})` : name;
if (names.indexOf(newName.toLowerCase()) !== -1) {
index++;
return getUniqueName(names, name, index);
}
return newName;
};

module.exports = {
load,
sha1,
checkKeyExists,
trim,
getUniqueName,
};