mirror of
https://github.com/strapi/strapi.git
synced 2025-07-23 09:00:19 +00:00
73 lines
2.8 KiB
JavaScript
73 lines
2.8 KiB
JavaScript
'use strict';
|
|
|
|
const { migrate } = require('./migrate');
|
|
const { areScalarAttributesOnly } = require('./utils');
|
|
|
|
const TMP_TABLE_NAME = '__tmp__i18n_field_migration';
|
|
|
|
const batchInsertInTmpTable = async ({ updatesInfo }, { transacting: trx }) => {
|
|
const tmpEntries = [];
|
|
updatesInfo.forEach(({ entriesIdsToUpdate, attributesValues }) => {
|
|
entriesIdsToUpdate.forEach(id => {
|
|
tmpEntries.push({ id, ...attributesValues });
|
|
});
|
|
});
|
|
await trx.batchInsert(TMP_TABLE_NAME, tmpEntries, 100);
|
|
};
|
|
|
|
const updateFromTmpTable = async ({ model, attributesToMigrate }, { transacting: trx }) => {
|
|
const collectionName = model.collectionName;
|
|
if (model.client === 'pg') {
|
|
const substitutes = attributesToMigrate.map(() => '?? = ??.??').join(',');
|
|
const bindings = [collectionName];
|
|
attributesToMigrate.forEach(attr => bindings.push(attr, TMP_TABLE_NAME, attr));
|
|
bindings.push(TMP_TABLE_NAME, collectionName, TMP_TABLE_NAME);
|
|
|
|
await trx.raw(`UPDATE ?? SET ${substitutes} FROM ?? WHERE ??.id = ??.id;`, bindings);
|
|
} else if (model.client === 'mysql') {
|
|
const substitutes = attributesToMigrate.map(() => '??.?? = ??.??').join(',');
|
|
const bindings = [collectionName, TMP_TABLE_NAME, collectionName, TMP_TABLE_NAME];
|
|
attributesToMigrate.forEach(attr => bindings.push(collectionName, attr, TMP_TABLE_NAME, attr));
|
|
|
|
await trx.raw(`UPDATE ?? JOIN ?? ON ??.id = ??.id SET ${substitutes};`, bindings);
|
|
}
|
|
};
|
|
|
|
const createTmpTable = async ({ ORM, attributesToMigrate, model }) => {
|
|
const columnsToCopy = ['id', ...attributesToMigrate];
|
|
await deleteTmpTable({ ORM });
|
|
await ORM.knex.raw(`CREATE TABLE ?? AS ??`, [
|
|
TMP_TABLE_NAME,
|
|
ORM.knex
|
|
.select(columnsToCopy)
|
|
.from(model.collectionName)
|
|
.whereRaw('?', 0),
|
|
]);
|
|
};
|
|
|
|
const deleteTmpTable = ({ ORM }) => ORM.knex.schema.dropTableIfExists(TMP_TABLE_NAME);
|
|
|
|
const migrateForBookshelf = async ({ ORM, model, attributesToMigrate }) => {
|
|
const onlyScalarAttrs = areScalarAttributesOnly({ model, attributes: attributesToMigrate });
|
|
|
|
// optimize migration for pg and mysql when there are only scalar attributes to migrate
|
|
if (onlyScalarAttrs && ['pg', 'mysql'].includes(model.client)) {
|
|
// create table outside of the transaction because mysql doesn't accept the creation inside
|
|
await createTmpTable({ ORM, attributesToMigrate, model });
|
|
await ORM.knex.transaction(async transacting => {
|
|
await migrate(
|
|
{ model, attributesToMigrate },
|
|
{ migrateFn: batchInsertInTmpTable, transacting }
|
|
);
|
|
await updateFromTmpTable({ model, attributesToMigrate }, { transacting });
|
|
});
|
|
await deleteTmpTable({ ORM });
|
|
} else {
|
|
await ORM.knex.transaction(async transacting => {
|
|
await migrate({ model, attributesToMigrate }, { transacting });
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = migrateForBookshelf;
|