strapi/packages/plugins/i18n/server/migrations/field/migrate-for-bookshelf.js

73 lines
2.8 KiB
JavaScript
Raw Normal View History

2021-02-18 18:42:28 +01:00
'use strict';
const { migrate } = require('./migrate');
2021-04-09 11:09:34 +02:00
const { areScalarAttributesOnly } = require('./utils');
2021-02-25 17:40:14 +01:00
2021-03-02 16:42:17 +01:00
const TMP_TABLE_NAME = '__tmp__i18n_field_migration';
const batchInsertInTmpTable = async ({ updatesInfo }, { transacting: trx }) => {
2021-03-02 16:42:17 +01:00
const tmpEntries = [];
updatesInfo.forEach(({ entriesIdsToUpdate, attributesValues }) => {
2022-08-08 23:33:39 +02:00
entriesIdsToUpdate.forEach((id) => {
2021-03-02 16:42:17 +01:00
tmpEntries.push({ id, ...attributesValues });
});
});
await trx.batchInsert(TMP_TABLE_NAME, tmpEntries, 100);
2021-03-01 11:26:44 +01:00
};
2021-04-09 11:09:34 +02:00
const updateFromTmpTable = async ({ model, attributesToMigrate }, { transacting: trx }) => {
2022-08-08 15:50:34 +02:00
const { collectionName } = model;
2021-03-02 16:42:17 +01:00
if (model.client === 'pg') {
// IMPORTANT TODO: use postgres schema
2021-04-09 11:09:34 +02:00
const substitutes = attributesToMigrate.map(() => '?? = ??.??').join(',');
2021-03-11 10:41:35 +01:00
const bindings = [collectionName];
2022-08-08 23:33:39 +02:00
attributesToMigrate.forEach((attr) => bindings.push(attr, TMP_TABLE_NAME, attr));
2021-03-02 16:42:17 +01:00
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') {
2021-04-09 11:09:34 +02:00
const substitutes = attributesToMigrate.map(() => '??.?? = ??.??').join(',');
2021-03-11 10:41:35 +01:00
const bindings = [collectionName, TMP_TABLE_NAME, collectionName, TMP_TABLE_NAME];
2022-08-08 23:33:39 +02:00
attributesToMigrate.forEach((attr) =>
bindings.push(collectionName, attr, TMP_TABLE_NAME, attr)
);
2021-03-02 16:42:17 +01:00
await trx.raw(`UPDATE ?? JOIN ?? ON ??.id = ??.id SET ${substitutes};`, bindings);
}
};
2021-02-25 17:40:14 +01:00
2021-04-09 11:09:34 +02:00
const createTmpTable = async ({ ORM, attributesToMigrate, model }) => {
const columnsToCopy = ['id', ...attributesToMigrate];
2021-03-19 12:12:51 +01:00
await deleteTmpTable({ ORM });
2021-02-25 17:40:14 +01:00
await ORM.knex.raw(`CREATE TABLE ?? AS ??`, [
TMP_TABLE_NAME,
2022-08-08 23:33:39 +02:00
ORM.knex.select(columnsToCopy).from(model.collectionName).whereRaw('?', 0),
2021-02-25 17:40:14 +01:00
]);
2021-03-02 16:42:17 +01:00
};
2021-02-25 17:40:14 +01:00
2021-03-02 16:42:17 +01:00
const deleteTmpTable = ({ ORM }) => ORM.knex.schema.dropTableIfExists(TMP_TABLE_NAME);
2021-04-09 11:09:34 +02:00
const migrateForBookshelf = async ({ ORM, model, attributesToMigrate }) => {
const onlyScalarAttrs = areScalarAttributesOnly({ model, attributes: attributesToMigrate });
2021-03-18 18:27:15 +01:00
// optimize migration for pg and mysql when there are only scalar attributes to migrate
if (onlyScalarAttrs && ['pg', 'mysql'].includes(model.client)) {
2021-03-19 10:21:56 +01:00
// create table outside of the transaction because mysql doesn't accept the creation inside
2021-04-09 11:09:34 +02:00
await createTmpTable({ ORM, attributesToMigrate, model });
2022-08-08 23:33:39 +02:00
await ORM.knex.transaction(async (transacting) => {
2021-04-09 11:09:34 +02:00
await migrate(
{ model, attributesToMigrate },
{ migrateFn: batchInsertInTmpTable, transacting }
);
await updateFromTmpTable({ model, attributesToMigrate }, { transacting });
2021-03-18 18:27:15 +01:00
});
await deleteTmpTable({ ORM });
} else {
2022-08-08 23:33:39 +02:00
await ORM.knex.transaction(async (transacting) => {
2021-04-09 11:09:34 +02:00
await migrate({ model, attributesToMigrate }, { transacting });
2021-03-18 18:27:15 +01:00
});
2021-02-25 17:40:14 +01:00
}
};
2021-03-02 17:09:35 +01:00
module.exports = migrateForBookshelf;