From a8aa89b5e3c12f4247ed5b293e26488cc7002c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Georget?= Date: Tue, 19 Apr 2016 17:07:21 +0200 Subject: [PATCH] Migration automation alpha version --- .../lib/builder/createTable.js | 36 +++- .../lib/builder/relations.js | 178 ++++++++++++------ .../columns/dropColumn-unique.template | 2 +- .../builder/columns/dropForeign.template | 2 +- .../templates/migration.template | 2 - 5 files changed, 145 insertions(+), 75 deletions(-) diff --git a/packages/strapi-generate-migrations/lib/builder/createTable.js b/packages/strapi-generate-migrations/lib/builder/createTable.js index 6c55685f1e..d6ecf48ad5 100755 --- a/packages/strapi-generate-migrations/lib/builder/createTable.js +++ b/packages/strapi-generate-migrations/lib/builder/createTable.js @@ -23,19 +23,37 @@ module.exports = function (models, modelName) { // Then, every `up` logic of every model call the // `./builder/tables/createTableIfNotExists` template. const tplTableCreate = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'tables', 'createTableIfNotExists.template'), 'utf8'); - _.set(models[modelName], 'up.others', _.unescape(_.template(tplTableCreate)({ - models: models, - tableName: modelName, - attributes: models[modelName].attributes, - options: models[modelName].options - }))); + if (_.isEmpty(_.get(models[modelName], 'up.others'))) { + console.log(models[modelName]); + _.set(models[modelName], 'up.others', _.unescape(_.template(tplTableCreate)({ + models: models, + tableName: modelName, + attributes: models[modelName].attributes, + options: models[modelName].options + }))); + } else { + models[modelName].up.others += _.unescape(_.template(tplTableCreate)({ + models: models, + tableName: modelName, + attributes: models[modelName].attributes, + options: models[modelName].options + })); + } + // Template: drop the table for the `down` export. // This adds a `down` logic for the current model. // Then, every `down` logic of every model call the // `./builder/tables/dropTable` template. const tplTableDrop = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'tables', 'dropTable.template'), 'utf8'); - _.set(models[modelName], 'down.others', _.unescape(_.template(tplTableDrop)({ - tableName: modelName - }))); + + if (_.isEmpty(_.get(models[modelName], 'down.others'))) { + _.set(models[modelName], 'down.others', _.unescape(_.template(tplTableDrop)({ + tableName: modelName + }))); + } else { + models[modelName].down.others += _.unescape(_.template(tplTableDrop)({ + tableName: modelName + })); + } }; diff --git a/packages/strapi-generate-migrations/lib/builder/relations.js b/packages/strapi-generate-migrations/lib/builder/relations.js index d44bd2c1c8..b3b47c8278 100755 --- a/packages/strapi-generate-migrations/lib/builder/relations.js +++ b/packages/strapi-generate-migrations/lib/builder/relations.js @@ -31,11 +31,10 @@ module.exports = function (rootModels, modelName, details, attribute, toDrop, on if (!onlyDrop && toDrop) { - console.log("#1 : " + modelName); infos = utilsModels.getNature(details, attribute, rootModels); oldInfos = utilsModels.getNature(_.get(rootModels[modelName].oldAttributes, attribute), attribute, history); - const isDifferentVerbose = oldInfos.hasOwnProperty('verbose') && oldInfos.verbose === infos.verbose ? false : true; + const isDifferentVerbose = oldInfos.hasOwnProperty('nature') && oldInfos.nature === infos.nature ? false : true; if (isDifferentVerbose) { handleRelation(oldInfos, history, modelName, _.get(rootModels[modelName].oldAttributes, attribute), attribute, true, true); @@ -43,13 +42,11 @@ module.exports = function (rootModels, modelName, details, attribute, toDrop, on } else { handleRelation(infos, rootModels, modelName, details, attribute, true, true); } - } else if (onlyDrop && toDrop) { - console.log("#2 : " + modelName); + } else if (onlyDrop || toDrop) { oldInfos = utilsModels.getNature(_.get(rootModels[modelName].oldAttributes, attribute), attribute, history); handleRelation(oldInfos, history, modelName, _.get(rootModels[modelName].oldAttributes, attribute), attribute, true, true); } else { - console.log("#3 : " + modelName); infos = utilsModels.getNature(details, attribute, rootModels); handleRelation(infos, rootModels, modelName, details, attribute); @@ -57,8 +54,19 @@ module.exports = function (rootModels, modelName, details, attribute, toDrop, on function handleRelation (infos, models, modelName, details, attribute, toDrop, onlyDrop) { - _.set(rootModels[modelName].attributes, attribute + '.create', {}); - _.set(rootModels[modelName].attributes, attribute + '.delete', {}); + if (_.isEmpty(_.get(rootModels[modelName].attributes, attribute + '.create'))) { + _.set(rootModels[modelName].attributes, attribute + '.create', { + drop: '', + others: '' + }); + } + + if (_.isEmpty(_.get(rootModels[modelName].attributes, attribute + '.delete'))) { + _.set(rootModels[modelName].attributes, attribute + '.delete', { + drop: '', + others: '' + }); + } // If it's a "one-to-one" relationship. if (infos.verbose === 'hasOne') { @@ -68,26 +76,35 @@ module.exports = function (rootModels, modelName, details, attribute, toDrop, on // Define PK column. details.column = utilsBookShelf.getPK(modelName, undefined, models); - // Template: create a new column thanks to the attribute's relation. - // Simply make a `create` template for this attribute wich will be added - // to the table template-- either `./builder/tables/selectTable` or - // `./builder/tables/createTableIfNotExists`. - tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'hasOne.template'), 'utf8'); - models[modelName].attributes[attribute].create.others = _.unescape(_.template(tplRelationUp)({ - tableName: modelName, - attribute: attribute, - details: details - })); + if (!toDrop) { + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'hasOne.template'), 'utf8'); + models[modelName].attributes[attribute].create.others += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details + })); - // Template: drop the column. - // Simply make a `delete` template for this attribute wich drop the column - // with the `./builder/columns/dropColumn` template. - tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn-unique.template'), 'utf8'); - models[modelName].attributes[attribute].delete.others = _.unescape(_.template(tplRelationDown)({ - tableName: modelName, - attribute: attribute, - details: details - })); + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn-unique.template'), 'utf8'); + models[modelName].attributes[attribute].delete.others += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details + })); + } else { + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn-unique.template'), 'utf8'); + models[modelName].attributes[attribute].create.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details + })); + + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'hasOne.template'), 'utf8'); + models[modelName].attributes[attribute].delete.drop += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details + })); + } } else if (infos.verbose === 'belongsTo') { // Force singular foreign key. details.attribute = pluralize.singular(details.model); @@ -96,48 +113,85 @@ module.exports = function (rootModels, modelName, details, attribute, toDrop, on details.column = utilsBookShelf.getPK(modelName, undefined, models); if (infos.nature === 'oneToMany' || infos.nature === 'oneWay') { - // Template: create a new column thanks to the attribute's relation. - // Simply make a `create` template for this attribute wich will be added - // to the table template-- either `./builder/tables/selectTable` or - // `./builder/tables/createTableIfNotExists`. + if (!toDrop) { + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo.template'), 'utf8'); + rootModels[modelName].attributes[attribute].create.others += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details, + nature: infos.nature + })); + + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn.template'), 'utf8'); + rootModels[modelName].attributes[attribute].delete.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details + })); + } else { + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropForeign.template'), 'utf8'); + rootModels[modelName].attributes[attribute].create.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details, + })); + + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo.template'), 'utf8'); + rootModels[modelName].attributes[attribute].delete.others += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details, + nature: infos.nature + })); + } + } else { + if (!toDrop) { + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo-unique.template'), 'utf8'); + rootModels[modelName].attributes[attribute].create.others += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details + })); + + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn-unique.template'), 'utf8'); + rootModels[modelName].attributes[attribute].delete.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details + })); + } else { + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn.template'), 'utf8'); + rootModels[modelName].attributes[attribute].create.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details, + })); + + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo.template'), 'utf8'); + rootModels[modelName].attributes[attribute].delete.others += _.unescape(_.template(tplRelationUp)({ + tableName: modelName, + attribute: attribute, + details: details, + nature: infos.nature + })); + } + } + } else if (infos.verbose === 'hasMany') { + if (toDrop) { + tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropForeign.template'), 'utf8'); + rootModels[modelName].attributes[attribute].create.drop += _.unescape(_.template(tplRelationDown)({ + tableName: modelName, + attribute: attribute, + details: details, + })); + tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo.template'), 'utf8'); - rootModels[modelName].attributes[attribute].create.others = _.unescape(_.template(tplRelationUp)({ + rootModels[modelName].attributes[attribute].delete.others += _.unescape(_.template(tplRelationUp)({ tableName: modelName, attribute: attribute, details: details, nature: infos.nature })); - - // Template: drop the column. - // Simply make a `delete` template for this attribute wich drop the column - // with the `./builder/columns/dropColumn` template. - tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn.template'), 'utf8'); - rootModels[modelName].attributes[attribute].delete.drop = _.unescape(_.template(tplRelationDown)({ - tableName: modelName, - attribute: attribute, - details: details - })); - } else { - // Template: create a new column thanks to the attribute's relation. - // Simply make a `create` template for this attribute wich will be added - // to the table template-- either `./builder/tables/selectTable` or - // `./builder/tables/createTableIfNotExists`. - tplRelationUp = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'relations', 'belongsTo-unique.template'), 'utf8'); - rootModels[modelName].attributes[attribute].create.others = _.unescape(_.template(tplRelationUp)({ - tableName: modelName, - attribute: attribute, - details: details - })); - - // Template: drop the column. - // Simply make a `delete` template for this attribute wich drop the column - // with the `./builder/columns/dropColumn` template. - tplRelationDown = fs.readFileSync(path.resolve(__dirname, '..', '..', 'templates', 'builder', 'columns', 'dropColumn-unique.template'), 'utf8'); - rootModels[modelName].attributes[attribute].delete.drop = _.unescape(_.template(tplRelationDown)({ - tableName: modelName, - attribute: attribute, - details: details - })); } } else if (infos.verbose === 'belongsToMany') { // Otherwise if it's a "many-to-many" relationship. diff --git a/packages/strapi-generate-migrations/templates/builder/columns/dropColumn-unique.template b/packages/strapi-generate-migrations/templates/builder/columns/dropColumn-unique.template index f687976b5a..172ab78ee0 100644 --- a/packages/strapi-generate-migrations/templates/builder/columns/dropColumn-unique.template +++ b/packages/strapi-generate-migrations/templates/builder/columns/dropColumn-unique.template @@ -1,3 +1,3 @@ // Delete the `<%= attribute %>` column with unique constraint. -table.dropUnique('<%= attribute %>').dropColumn('<%= attribute %>') +table.dropUnique('<%= tableName.toLowerCase() %>_<%= attribute %>_unique').dropColumn('<%= attribute %>') diff --git a/packages/strapi-generate-migrations/templates/builder/columns/dropForeign.template b/packages/strapi-generate-migrations/templates/builder/columns/dropForeign.template index 3d09fd04ef..5b103832af 100644 --- a/packages/strapi-generate-migrations/templates/builder/columns/dropForeign.template +++ b/packages/strapi-generate-migrations/templates/builder/columns/dropForeign.template @@ -1,3 +1,3 @@ // Delete the foreign key on `<%= attribute %>` column. -table.dropForeign('<%= attribute %>') +table.dropForeign('<%= attribute %>').dropColumn('<%= attribute %>') diff --git a/packages/strapi-generate-migrations/templates/migration.template b/packages/strapi-generate-migrations/templates/migration.template index 9c66874a8f..2c527e95e7 100755 --- a/packages/strapi-generate-migrations/templates/migration.template +++ b/packages/strapi-generate-migrations/templates/migration.template @@ -58,8 +58,6 @@ exports.down = function(connection, Promise) { } }); - console.log("MIGRATION: " + dropped, onlyDrop); - if (dropped === true && onlyDrop === false) { %> return Promise.all([ <% _.forEach(models, function(definition, model) { %><%= _.get(models[model], 'down.drop') %><% }); %>