diff --git a/packages/strapi-bookshelf/lib/index.js b/packages/strapi-bookshelf/lib/index.js index ad2f73c51a..0c5b2c56a7 100755 --- a/packages/strapi-bookshelf/lib/index.js +++ b/packages/strapi-bookshelf/lib/index.js @@ -310,10 +310,105 @@ module.exports = function(strapi) { target[model]._attributes = definition.attributes; databaseUpdate.push(new Promise(async (resolve) => { - const tableExist = await ORM.knex.schema.hasTable(loadedModel.tableName); + const handler = async (table, attributes, tableExist) => { + // Generate fields type + const generateColumns = (attrs, start) => { + return Object.keys(attrs).reduce((acc, attr) => { + const attribute = attributes[attr]; + + let type; + + if (!attribute.type) { + const relation = definition.associations.find((association) => { + return association.alias === attr; + }); + + switch (relation.nature) { + case 'manyToOne': + type = definition.client === 'pg' ? 'integer' : 'int'; + break; + default: + return acc; + } + } else { + switch (attribute.type) { + case 'string': + case 'text': + case 'password': + case 'email': + case 'json': + type = 'text'; + break; + case 'integer': + case 'biginteger': + case 'float': + case 'decimal': + type = definition.client === 'pg' ? 'integer' : 'int'; + break; + case 'date': + case 'time': + case 'datetime': + case 'timestamp': + type = definition.client === 'pg' ? 'timestamp with time zone' : 'timestamp'; + break; + case 'boolean': + type = 'boolean'; + break; + default: + } + } + + acc.push(`${quote}${attr}${quote} ${type}`); + + return acc; + }, start); + }; + + if (!tableExist) { + const columns = generateColumns(attributes, [`id ${definition.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY`]).join(',\n\r'); + + // Create table + await ORM.knex.raw(` + CREATE TABLE ${quote}${table}${quote} ( + ${columns} + ) + `); + } else { + const columns = Object.keys(attributes); + + // Fetch existing column + const columnsExist = await Promise.all(columns.map(attribute => + ORM.knex.schema.hasColumn(table, attribute) + )); + + const columnsToAdd = {}; + + // Get columns to add + columnsExist.forEach((columnExist, index) => { + const attribute = attributes[columns[index]]; + + if (!columnExist) { + columnsToAdd[columns[index]] = attribute; + } + }); + + // Generate and execute query to add missing column + if (Object.keys(columnsToAdd).length > 0) { + const columns = generateColumns(columnsToAdd, []); + const queries = columns.reduce((acc, attribute) => { + acc.push(`ALTER TABLE ${quote}${table}${quote} ADD ${attribute};`) + return acc; + }, []).join('\n\r'); + + await ORM.knex.raw(queries); + } + } + }; const quote = definition.client === 'pg' ? '"' : '`'; + const tableExist = await ORM.knex.schema.hasTable(loadedModel.tableName); + // Add created_at and updated_at field if timestamp option is true if (loadedModel.hasTimestamps) { definition.attributes['created_at'] = definition.attributes['updated_at'] = { @@ -321,97 +416,31 @@ module.exports = function(strapi) { }; } - // Generate fields type - const generateColumns = (attributes, start) => { - return Object.keys(attributes).reduce((acc, attr) => { - const attribute = definition.attributes[attr]; + await handler(loadedModel.tableName, definition.attributes, tableExist); - let type; + const morphRelations = definition.associations.find((association) => { + return association.nature.toLowerCase().includes('morph'); + }); - if (!attribute.type) { - const relation = definition.associations.find((association) => { - return association.alias === attr; - }); + if (morphRelations) { + const tableExist = await ORM.knex.schema.hasTable(`${loadedModel.tableName}_morph`); - switch (relation.nature) { - case 'manyToOne': - type = definition.client === 'pg' ? 'integer' : 'int'; - break; - default: - return acc; - } - } else { - switch (attribute.type) { - case 'string': - case 'text': - case 'password': - case 'email': - case 'json': - type = 'text'; - break; - case 'integer': - case 'biginteger': - case 'float': - case 'decimal': - type = definition.client === 'pg' ? 'integer' : 'int'; - break; - case 'date': - case 'time': - case 'datetime': - case 'timestamp': - type = definition.client === 'pg' ? 'timestamp with time zone' : 'timestamp'; - break; - case 'boolean': - type = 'boolean'; - break; - default: - } + const attributes = { + [`${loadedModel.tableName}_id`]: { + type: 'integer' + }, + [`${morphRelations.alias}_id`]: { + type: 'integer' + }, + [`${morphRelations.alias}_type`]: { + type: 'text' + }, + [definition.attributes[morphRelations.alias].filter]: { + type: 'text' } + }; - acc.push(`${quote}${attr}${quote} ${type}`); - - return acc; - }, start); - }; - - if (!tableExist) { - const columns = generateColumns(definition.attributes, [`id ${definition.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY`]).join(',\n\r'); - - // Create table - await ORM.knex.raw(` - CREATE TABLE ${quote}${loadedModel.tableName}${quote} ( - ${columns} - ) - `); - } else { - const columns = Object.keys(definition.attributes); - - // Fetch existing column - const columnsExist = await Promise.all(columns.map(attribute => - ORM.knex.schema.hasColumn(loadedModel.tableName, attribute) - )); - - const columnsToAdd = {}; - - // Get columns to add - columnsExist.forEach((columnExist, index) => { - const attribute = definition.attributes[columns[index]]; - - if (!columnExist) { - columnsToAdd[columns[index]] = attribute; - } - }); - - // Generate and execute query to add missing column - if (Object.keys(columnsToAdd).length > 0) { - const columns = generateColumns(columnsToAdd, []); - const queries = columns.reduce((acc, attribute) => { - acc.push(`ALTER TABLE ${quote}${loadedModel.tableName}${quote} ADD ${attribute};`) - return acc; - }, []).join('\n\r'); - - await ORM.knex.raw(queries); - } + await handler(`${loadedModel.tableName}_morph`, attributes, tableExist); } resolve(); diff --git a/packages/strapi-plugin-upload/config/functions/bootstrap.js b/packages/strapi-plugin-upload/config/functions/bootstrap.js index d5cd3f6ca2..80795866a2 100644 --- a/packages/strapi-plugin-upload/config/functions/bootstrap.js +++ b/packages/strapi-plugin-upload/config/functions/bootstrap.js @@ -13,39 +13,6 @@ const _ = require('lodash'); const fs = require('fs'); module.exports = async cb => { - const Model = strapi.plugins.upload.models.file; - - if (Model.orm === 'bookshelf') { - const hasTable = await strapi.connections[Model.connection].schema.hasTable(Model.tableName || Model.collectionName); - - if (!hasTable) { - const quote = Model.client === 'pg' ? '"' : '`'; - - await strapi.connections[Model.connection].raw(` - CREATE TABLE ${quote}${Model.tableName || Model.collectionName}${quote} ( - id ${Model.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY, - name text, - hash text, - ext text, - mime text, - size text, - url text, - provider text, - updated_at ${Model.client === 'pg' ? 'timestamp with time zone' : 'timestamp'}, - created_at ${Model.client === 'pg' ? 'timestamp with time zone' : 'timestamp'} - ); - - CREATE TABLE ${quote}upload_file_morph${quote} ( - id ${Model.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY, - upload_file_id ${Model.client === 'pg' ? 'integer' : 'int'}, - related_id ${Model.client === 'pg' ? 'integer' : 'int'}, - related_type text, - field text - ); - `); - } - } - // set plugin store const pluginStore = strapi.store({ environment: strapi.config.environment,