Files
2025-05-02 13:37:11 +02:00

78 lines
3.0 KiB
TypeScript

import { Migrations } from 'meteor/percolate:migrations';
import Libraries from '/imports/api/library/Libraries';
import { rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
import Docs, { DOC_ROOT_ID } from '/imports/api/docs/Docs';
import LibraryNodes from '/imports/api/library/LibraryNodes';
import { TreeDoc } from '/imports/api/parenting/ChildSchema';
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables';
// Git version 2.0.59
// Database version 3
Migrations.add({
version: 3,
name: 'Changes parenting from array of ancestors to nested sets',
up: Meteor.wrapAsync(async (_, next) => {
console.log('migrating up library nodes 2 -> 3');
await migrateCollection('libraryNodes');
console.log('migrating up creature props 2 -> 3');
await migrateCollection('creatureProperties');
console.log('migrating up docs 2 -> 3');
await migrateCollection('docs');
console.log('New parenting schema fields added, if it was done correctly remove the old fields manually');
console.log('removing all CreatureVariables, creatures will add them back the next time they recalculate');
CreatureVariables.remove({});
console.log('Rebuilding nested sets for all libraries'); // Characters rebuild themselves on recompute
const libraryIds = await Libraries.find().mapAsync((library) => library._id);
for (const [index, libraryId] of libraryIds.entries()) {
console.log('Rebuilding nested sets for library', index + 1, 'of', libraryIds.length);
await rebuildNestedSets(LibraryNodes as Mongo.Collection<TreeDoc>, libraryId);
}
console.log('Removing all docs and replacing them with default docs');
Docs.remove({});
Assets.getText('docs/defaultDocs.json', (error, string) => {
const docs = JSON.parse(string)
docs.forEach(doc => Docs.insert(doc));
});
rebuildNestedSets(Docs, DOC_ROOT_ID);
next();
}),
down() {
throw 'Migrating from version 3 down to version 2 is not supported'
},
});
export function migrateCollection(collectionName: string) {
const collection = Mongo.Collection.get(collectionName);
// Copy the parent id field and the root ancestor to the new structure
// Using the mongo aggregation API
// Waring: This will destroy parenting data if the old parenting fields are deleted
return collection.rawCollection().updateMany({
'root.id': undefined,
}, [
{
$addFields: {
'root': { $arrayElemAt: ['$ancestors', 0] },
'parentId': {
// Parent ID must refer to a document in the same collection, so remove the parent ID
// if the parent reference refers to a different collection
$cond: {
if: { $eq: [collectionName, '$parent.collection'] },
then: '$parent.id',
else: '$$REMOVE',
}
},
// Set left and right to current order so that order is maintained on the first re-build
// of the tree structure
'left': '$order',
'right': '$order',
}
},
]);
}