124 lines
4.4 KiB
JavaScript
124 lines
4.4 KiB
JavaScript
import { createId } from '@paralleldrive/cuid2';
|
|
import { snakeCase } from 'lodash/fp';
|
|
|
|
const QUERIES = {
|
|
async postgres (knex, params) {
|
|
const res = await knex.raw(`
|
|
SELECT :tableName:.id as id, string_agg(DISTINCT :inverseJoinColumn:::character varying, ',') as other_ids
|
|
FROM :tableName:
|
|
LEFT JOIN :joinTableName: ON :tableName:.id = :joinTableName:.:joinColumn:
|
|
WHERE :tableName:.document_id IS NULL
|
|
GROUP BY :tableName:.id, :joinTableName:.:joinColumn:
|
|
LIMIT 1;
|
|
`, params);
|
|
return res.rows;
|
|
},
|
|
async mysql (knex, params) {
|
|
const [res] = await knex.raw(`
|
|
SELECT :tableName:.id as id, group_concat(DISTINCT :inverseJoinColumn:) as other_ids
|
|
FROM :tableName:
|
|
LEFT JOIN :joinTableName: ON :tableName:.id = :joinTableName:.:joinColumn:
|
|
WHERE :tableName:.document_id IS NULL
|
|
GROUP BY :tableName:.id, :joinTableName:.:joinColumn:
|
|
LIMIT 1;
|
|
`, params);
|
|
return res;
|
|
},
|
|
async sqlite (knex, params) {
|
|
return knex.raw(`
|
|
SELECT :tableName:.id as id, group_concat(DISTINCT :inverseJoinColumn:) as other_ids
|
|
FROM :tableName:
|
|
LEFT JOIN :joinTableName: ON :tableName:.id = :joinTableName:.:joinColumn:
|
|
WHERE :tableName:.document_id IS NULL
|
|
GROUP BY :joinTableName:.:joinColumn:
|
|
LIMIT 1;
|
|
`, params);
|
|
}
|
|
};
|
|
const getNextIdsToCreateDocumentId = async (db, knex, { joinColumn, inverseJoinColumn, tableName, joinTableName })=>{
|
|
const res = await QUERIES[db.dialect.client](knex, {
|
|
joinColumn,
|
|
inverseJoinColumn,
|
|
tableName,
|
|
joinTableName
|
|
});
|
|
if (res.length > 0) {
|
|
const row = res[0];
|
|
const otherIds = row.other_ids ? row.other_ids.split(',').map((v)=>parseInt(v, 10)) : [];
|
|
return [
|
|
row.id,
|
|
...otherIds
|
|
];
|
|
}
|
|
return [];
|
|
};
|
|
// Migrate document ids for tables that have localizations
|
|
const migrateDocumentIdsWithLocalizations = async (db, knex, meta)=>{
|
|
const singularName = meta.singularName.toLowerCase();
|
|
const joinColumn = snakeCase(`${singularName}_id`);
|
|
const inverseJoinColumn = snakeCase(`inv_${singularName}_id`);
|
|
let ids;
|
|
do {
|
|
ids = await getNextIdsToCreateDocumentId(db, knex, {
|
|
joinColumn,
|
|
inverseJoinColumn,
|
|
tableName: meta.tableName,
|
|
joinTableName: snakeCase(`${meta.tableName}_localizations_links`)
|
|
});
|
|
if (ids.length > 0) {
|
|
await knex(meta.tableName).update({
|
|
document_id: createId()
|
|
}).whereIn('id', ids);
|
|
}
|
|
}while (ids.length > 0)
|
|
};
|
|
// Migrate document ids for tables that don't have localizations
|
|
const migrationDocumentIds = async (db, knex, meta)=>{
|
|
let updatedRows;
|
|
do {
|
|
updatedRows = await knex(meta.tableName).update({
|
|
document_id: createId()
|
|
}).whereIn('id', knex(meta.tableName).select('id').from(knex(meta.tableName).select('id').whereNull('document_id').limit(1).as('sub_query')));
|
|
}while (updatedRows > 0)
|
|
};
|
|
const createDocumentIdColumn = async (knex, tableName)=>{
|
|
await knex.schema.alterTable(tableName, (table)=>{
|
|
table.string('document_id');
|
|
});
|
|
};
|
|
const hasLocalizationsJoinTable = async (knex, tableName)=>{
|
|
const joinTableName = snakeCase(`${tableName}_localizations_links`);
|
|
return knex.schema.hasTable(joinTableName);
|
|
};
|
|
const createdDocumentId = {
|
|
name: '5.0.0-02-created-document-id',
|
|
async up (knex, db) {
|
|
// do sth
|
|
for (const meta of db.metadata.values()){
|
|
const hasTable = await knex.schema.hasTable(meta.tableName);
|
|
if (!hasTable) {
|
|
continue;
|
|
}
|
|
if ('documentId' in meta.attributes) {
|
|
// add column if doesn't exist
|
|
const hasDocumentIdColumn = await knex.schema.hasColumn(meta.tableName, 'document_id');
|
|
if (hasDocumentIdColumn) {
|
|
continue;
|
|
}
|
|
await createDocumentIdColumn(knex, meta.tableName);
|
|
if (await hasLocalizationsJoinTable(knex, meta.tableName)) {
|
|
await migrateDocumentIdsWithLocalizations(db, knex, meta);
|
|
} else {
|
|
await migrationDocumentIds(db, knex, meta);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async down () {
|
|
throw new Error('not implemented');
|
|
}
|
|
};
|
|
|
|
export { createdDocumentId };
|
|
//# sourceMappingURL=5.0.0-02-document-id.mjs.map
|