Fix sqlite column update

This commit is contained in:
Jim LAURIE 2019-02-14 16:23:29 +01:00
parent 5f48dbfbe2
commit fb04c4dcbe

View File

@ -471,7 +471,7 @@ module.exports = function(strapi) {
const type = getType(attribute, attr);
if (type) {
acc.push(`${quote}${attr}${quote} ${type}`);
acc.push(`${quote}${attr}${quote} ${type} ${attribute.required ? 'NOT' : ''} NULL `);
}
return acc;
@ -544,14 +544,12 @@ module.exports = function(strapi) {
}
};
if (!tableExist) {
const createTable = async (table) => {
const defaultAttributeDifinitions = {
mysql: [`id INT AUTO_INCREMENT NOT NULL PRIMARY KEY`],
pg: [`id SERIAL NOT NULL PRIMARY KEY`],
sqlite3: ['id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL']
};
let idAttributeBuilder = defaultAttributeDifinitions[definition.client];
if (definition.primaryKeyType === 'uuid' && definition.client === 'pg') {
idAttributeBuilder = ['id uuid NOT NULL DEFAULT uuid_generate_v4() NOT NULL PRIMARY KEY'];
@ -566,13 +564,16 @@ module.exports = function(strapi) {
${columns}
)
`);
};
if (!tableExist) {
await createTable(table);
// Generate indexes.
await generateIndexes(table, attributes);
await storeTable(table, attributes);
} else {
const columns = Object.keys(attributes);
// Fetch existing column
@ -594,6 +595,14 @@ module.exports = function(strapi) {
// Generate indexes for new attributes.
await generateIndexes(table, columnsToAdd);
let previousAttributes;
try {
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
} catch (err) {
await storeTable(table, attributes);
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
}
// Generate and execute query to add missing column
if (Object.keys(columnsToAdd).length > 0) {
const columns = generateColumns(columnsToAdd, []);
@ -605,31 +614,28 @@ module.exports = function(strapi) {
await Promise.all(queries.map(query => ORM.knex.raw(query)));
}
let previousAttributes;
try {
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
} catch (err) {
await storeTable(table, attributes);
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
}
let sqlite3Change = false;
// Execute query to update column type
await Promise.all(columns.map(attribute =>
new Promise(async (resolve) => {
if (JSON.stringify(previousAttributes[attribute]) === JSON.stringify(attributes[attribute])) {
return resolve();
} else {
sqlite3Change = true;
}
const type = getType(attributes[attribute], attribute);
if (type) {
const changeType = definition.client === 'pg' || definition.client === 'sqlite3'
if (type && definition.client !== 'sqlite3') {
const changeType = definition.client === 'pg'
? `ALTER COLUMN ${quote}${attribute}${quote} TYPE ${type} USING ${quote}${attribute}${quote}::${type}`
: `CHANGE ${quote}${attribute}${quote} ${quote}${attribute}${quote} ${type} `;
const changeRequired = definition.client === 'pg' || definition.client === 'sqlite3'
const changeRequired = definition.client === 'pg'
? `ALTER COLUMN ${quote}${attribute}${quote} ${attributes[attribute].required ? 'SET' : 'DROP'} NOT NULL`
: `CHANGE ${quote}${attribute}${quote} ${quote}${attribute}${quote} ${type} ${attributes[attribute].required ? 'NOT' : ''} NULL`;
await ORM.knex.raw(`ALTER TABLE ${quote}${table}${quote} ${changeType}`);
await ORM.knex.raw(`ALTER TABLE ${quote}${table}${quote} ${changeRequired}`);
}
@ -638,6 +644,28 @@ module.exports = function(strapi) {
})
));
if (sqlite3Change) {
await createTable(`tmp_${table}`);
try {
await ORM.knex.raw(`INSERT INTO ${quote}tmp_${table}${quote}(${Object.keys(attributes).join(' ,')}) SELECT ${Object.keys(attributes).join(' ,')} FROM ${quote}${table}${quote}`);
} catch (err) {
console.log('Warning!');
console.log('We can\'t migrate your data caused by the following error');
console.log();
console.log(err);
console.log();
console.log(`We created a new table "tmp_${table}" with your last update.`);
console.log(`We suggest you manually migrate your data from "${table}" to "tmp_${table}" and then to DROP and RENAME tables.`);
return false;
}
await ORM.knex.raw(`DROP TABLE ${quote}${table}${quote}`);
await ORM.knex.raw(`ALTER TABLE ${quote}tmp_${table}${quote} RENAME TO ${quote}${table}${quote}`);
await generateIndexes(table, attributes);
}
await storeTable(table, attributes);
}
};