diff --git a/app/constants/codes.js b/app/constants/codes.js index d81e89f..55cde21 100644 --- a/app/constants/codes.js +++ b/app/constants/codes.js @@ -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', diff --git a/app/controllers/positions.js b/app/controllers/positions.js index 43394d3..ff4bb1c 100644 --- a/app/controllers/positions.js +++ b/app/controllers/positions.js @@ -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 }) { diff --git a/app/controllers/tables.js b/app/controllers/tables.js index dc37bd2..a64a50d 100644 --- a/app/controllers/tables.js +++ b/app/controllers/tables.js @@ -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 => { @@ -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) { @@ -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] = []; @@ -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) { @@ -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, diff --git a/app/queries/positions.js b/app/queries/positions.js index be83dda..78bb974 100644 --- a/app/queries/positions.js +++ b/app/queries/positions.js @@ -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, @@ -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); + }, }; diff --git a/app/queries/tables.js b/app/queries/tables.js index 5b87079..f4bc723 100644 --- a/app/queries/tables.js +++ b/app/queries/tables.js @@ -113,4 +113,11 @@ module.exports = { bulkCreate(records) { return Tables.bulkCreate(records); }, + + getTableNames(baseId) { + return Tables.findAll({ + attributes: ['name'], + where: { baseId }, + }); + }, }; diff --git a/app/resolvers/positions.js b/app/resolvers/positions.js index c67f299..5ab009f 100644 --- a/app/resolvers/positions.js +++ b/app/resolvers/positions.js @@ -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', diff --git a/app/router/index.js b/app/router/index.js index c4cdb46..44991dc 100644 --- a/app/router/index.js +++ b/app/router/index.js @@ -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); diff --git a/app/util/helper.js b/app/util/helper.js index 3d363c3..d22d430 100755 --- a/app/util/helper.js +++ b/app/util/helper.js @@ -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, };