Added backend architecture to archive and restore creatures.
This commit is contained in:
57
app/imports/api/creature/archive/ArchivedCreatures.js
Normal file
57
app/imports/api/creature/archive/ArchivedCreatures.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
|
||||
// Archived creatures is an immutable collection of creatures that are no longer
|
||||
// in use and can be safely archived by the mongoDB hosting service.
|
||||
// It keeps the working datasets like creatureProperties much smaller
|
||||
// than they would otherwise be.
|
||||
let ArchivedCreatures = new Mongo.Collection('archivedCreatures');
|
||||
|
||||
// We use blackbox objects for everything:
|
||||
// - saves time checking every object against a schema
|
||||
// - doesn't accidentaly create indices defined in subschemas
|
||||
// - The objects we are archiving have already been checked against their
|
||||
// own schemas
|
||||
let ArchivedCreatureSchema = new SimpleSchema({
|
||||
owner: {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
// The primary index on this collection
|
||||
index: 1,
|
||||
},
|
||||
archiveDate: {
|
||||
type: Date,
|
||||
// Indexed so the archiving system can archive documents when they
|
||||
// get to a certain age
|
||||
index: 1,
|
||||
},
|
||||
creature: {
|
||||
type: Object,
|
||||
blackbox: true,
|
||||
},
|
||||
properties: {
|
||||
type: Array,
|
||||
},
|
||||
'properties.$': {
|
||||
type: Object,
|
||||
blackbox: true,
|
||||
},
|
||||
experiences: {
|
||||
type: Array,
|
||||
},
|
||||
'experiences.$': {
|
||||
type: Object,
|
||||
blackbox: true,
|
||||
},
|
||||
logs: {
|
||||
type: Array,
|
||||
},
|
||||
'logs.$': {
|
||||
type: Object,
|
||||
blackbox: true,
|
||||
},
|
||||
});
|
||||
|
||||
ArchivedCreatures.attachSchema(ArchivedCreatureSchema);
|
||||
|
||||
import '/imports/api/creature/archive/methods/index.js';
|
||||
export default ArchivedCreatures;
|
||||
66
app/imports/api/creature/archive/methods/archiveCreatures.js
Normal file
66
app/imports/api/creature/archive/methods/archiveCreatures.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import { assertOwnership } from '/imports/api/creature/creaturePermissions.js';
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import Experiences from '/imports/api/creature/experience/Experiences.js';
|
||||
import { removeCreatureWork } from '/imports/api/creature/removeCreature.js';
|
||||
import ArchivedCreatures from '/imports/api/creature/archive/ArchivedCreatures.js';
|
||||
|
||||
function archiveCreature(creatureId){
|
||||
// Build the archive document
|
||||
const creature = Creatures.findOne(creatureId);
|
||||
const properties = CreatureProperties.find({'ancestors.id': creatureId});
|
||||
const experiences = Experiences.find({creatureId});
|
||||
const logs = CreatureLogs.find({creatureId});
|
||||
let archiveCreature = {
|
||||
owner: creature.owner,
|
||||
archiveDate: new Date(),
|
||||
creature,
|
||||
properties,
|
||||
experiences,
|
||||
logs,
|
||||
};
|
||||
|
||||
// Insert it
|
||||
let id = ArchivedCreatures.insert(archiveCreature);
|
||||
|
||||
// Remove the original creature
|
||||
removeCreatureWork(creatureId);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
const archiveCreatures = new ValidatedMethod({
|
||||
name: 'Creatures.methods.archiveCreatures',
|
||||
validate: new SimpleSchema({
|
||||
creatureIds: {
|
||||
type: Array,
|
||||
max: 10,
|
||||
},
|
||||
'creatureIds.$': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
}).validator(),
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 1,
|
||||
timeInterval: 5000,
|
||||
},
|
||||
run({creatureIds}) {
|
||||
for (let id in creatureIds){
|
||||
assertOwnership(id, this.userId)
|
||||
}
|
||||
let archivedIds = [];
|
||||
for (let id in creatureIds){
|
||||
let archivedId = archiveCreature(id);
|
||||
archivedIds.push(archivedId);
|
||||
}
|
||||
return archivedIds;
|
||||
},
|
||||
});
|
||||
|
||||
export default archiveCreatures;
|
||||
2
app/imports/api/creature/archive/methods/index.js
Normal file
2
app/imports/api/creature/archive/methods/index.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import '/imports/api/creature/archive/methods/archiveCreatures.js';
|
||||
import '/imports/api/creature/archive/methods/restoreCreatures.js';
|
||||
63
app/imports/api/creature/archive/methods/restoreCreatures.js
Normal file
63
app/imports/api/creature/archive/methods/restoreCreatures.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import SimpleSchema from 'simpl-schema';
|
||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||
import { assertOwnership } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
import CreatureLogs from '/imports/api/creature/log/CreatureLogs.js';
|
||||
import Experiences from '/imports/api/creature/experience/Experiences.js';
|
||||
import ArchivedCreatures from '/imports/api/creature/archive/ArchivedCreatures.js';
|
||||
|
||||
function restoreCreature(archiveId){
|
||||
// Get the archive
|
||||
const archivedCreature = ArchivedCreatures.findOne(archiveId);
|
||||
|
||||
// Insert the creature sub documents
|
||||
// They still have their original _id's
|
||||
Creatures.insert(archivedCreature.creature);
|
||||
CreatureProperties.batchInsert(archivedCreature.properties);
|
||||
Experiences.batchInsert(archivedCreature.experiences);
|
||||
CreatureLogs.batchInsert(archivedCreature.logs);
|
||||
// Do not recompute. The creature was in a computed and ordered state when
|
||||
// we archived it, just restore everything as-is
|
||||
|
||||
// Remove the archived creature
|
||||
ArchivedCreatures.remove(archiveId);
|
||||
|
||||
return archivedCreature.creature._id;
|
||||
}
|
||||
|
||||
const restoreCreatures = new ValidatedMethod({
|
||||
name: 'Creatures.methods.restoreCreatures',
|
||||
validate: new SimpleSchema({
|
||||
archiveIds: {
|
||||
type: Array,
|
||||
max: 10,
|
||||
},
|
||||
'archiveIds.$': {
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
}).validator(),
|
||||
mixins: [RateLimiterMixin],
|
||||
rateLimit: {
|
||||
numRequests: 1,
|
||||
timeInterval: 5000,
|
||||
},
|
||||
run({archiveIds}) {
|
||||
for (let id in archiveIds){
|
||||
let archivedCreature = ArchivedCreatures.findOne(id, {
|
||||
fields: {owner: 1}
|
||||
});
|
||||
assertOwnership(archivedCreature, this.userId)
|
||||
}
|
||||
let creatureIds = [];
|
||||
for (let id in archiveIds){
|
||||
let creatureId = restoreCreature(id);
|
||||
creatureIds.push(creatureId);
|
||||
}
|
||||
return creatureIds;
|
||||
},
|
||||
});
|
||||
|
||||
export default restoreCreatures;
|
||||
18
app/imports/server/publications/archivedCreatures.js
Normal file
18
app/imports/server/publications/archivedCreatures.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import ArchivedCreatures from '/imports/api/creature/archive/ArchivedCreatures.js';
|
||||
|
||||
Meteor.publish('archivedCreatures', function(){
|
||||
this.autorun(function (){
|
||||
var userId = this.userId;
|
||||
if (!userId) {
|
||||
return [];
|
||||
}
|
||||
return ArchivedCreatures.find({
|
||||
owner: userId,
|
||||
}, {
|
||||
fields: {
|
||||
creature: 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -6,5 +6,6 @@ import '/imports/server/publications/experiences.js';
|
||||
import '/imports/server/publications/users.js';
|
||||
import '/imports/server/publications/icons.js';
|
||||
import '/imports/server/publications/tabletops.js';
|
||||
import '/imports/server/publications/slotFillers.js'
|
||||
import '/imports/server/publications/ownedDocuments.js'
|
||||
import '/imports/server/publications/slotFillers.js';
|
||||
import '/imports/server/publications/ownedDocuments.js';
|
||||
import '/imports/server/publications/archivedCreatures.js';
|
||||
|
||||
Reference in New Issue
Block a user