mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-24 18:56:32 -05:00
refactor(migrations): move cleanup code into migration
We cannot execute the cleanup script as a subprocess with sqlite, as we now wrap the migrations in a SAVEPOINT, which blocks a second process. This moves the cleanup code into the migration file, so it can be executed in-process. Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
parent
c83eb7ec7e
commit
f606a7825f
2 changed files with 112 additions and 114 deletions
103
bin/cleanup
103
bin/cleanup
|
@ -1,104 +1,7 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const logger = require('../lib/logger')
|
const cleanup = require('../lib/migrations/20200321153000-fix-account-deletion').cleanup
|
||||||
const models = require('../lib/models')
|
|
||||||
|
|
||||||
logger.info('Cleaning up notes that should already have been removed. Sorry.')
|
cleanup().then(() => {
|
||||||
|
|
||||||
async function cleanup () {
|
|
||||||
await models.Note.findAll({
|
|
||||||
include: [{
|
|
||||||
model: models.User,
|
|
||||||
as: 'owner',
|
|
||||||
attributes: ['id']
|
|
||||||
}],
|
|
||||||
attributes: ['id', 'ownerId']
|
|
||||||
}).then(async function (notes) {
|
|
||||||
for (let i = 0, noteCount = notes.length; i < noteCount; i++) {
|
|
||||||
const item = notes[i]
|
|
||||||
if (item.ownerId != null && !item.owner) {
|
|
||||||
await models.Note.destroy({
|
|
||||||
where: {
|
|
||||||
id: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
await models.Revision.destroy({
|
|
||||||
where: {
|
|
||||||
noteId: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
await models.Author.destroy({
|
|
||||||
where: {
|
|
||||||
noteId: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
logger.info(`Deleted note ${item.id} from user ${item.ownerId}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
await models.Author.findAll({
|
|
||||||
include: [{
|
|
||||||
model: models.User,
|
|
||||||
as: 'user',
|
|
||||||
attributes: ['id']
|
|
||||||
}],
|
|
||||||
attributes: ['id', 'userId']
|
|
||||||
}).then(async function (authors) {
|
|
||||||
for (let i = 0, authorCount = authors.length; i < authorCount; i++) {
|
|
||||||
const item = authors[i]
|
|
||||||
if (item.userId != null && !item.user) {
|
|
||||||
await models.Author.destroy({
|
|
||||||
where: {
|
|
||||||
id: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
logger.info(`Deleted authorship ${item.id} from user ${item.userId}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await models.Author.findAll({
|
|
||||||
include: [{
|
|
||||||
model: models.Note,
|
|
||||||
as: 'note',
|
|
||||||
attributes: ['id']
|
|
||||||
}],
|
|
||||||
attributes: ['id', 'noteId']
|
|
||||||
}).then(async function (authors) {
|
|
||||||
for (let i = 0, authorCount = authors.length; i < authorCount; i++) {
|
|
||||||
const item = authors[i]
|
|
||||||
if (item.noteId != null && !item.note) {
|
|
||||||
await models.Author.destroy({
|
|
||||||
where: {
|
|
||||||
id: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
logger.info(`Deleted authorship ${item.id} from note ${item.noteId}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
await models.Revision.findAll({
|
|
||||||
include: [{
|
|
||||||
model: models.Note,
|
|
||||||
as: 'note',
|
|
||||||
attributes: ['id']
|
|
||||||
}],
|
|
||||||
attributes: ['id', 'noteId']
|
|
||||||
}).then(async function (revisions) {
|
|
||||||
for (let i = 0, revisionCount = revisions.length; i < revisionCount; i++) {
|
|
||||||
const item = revisions[i]
|
|
||||||
if (item.noteId != null && !item.note) {
|
|
||||||
await models.Revision.destroy({
|
|
||||||
where: {
|
|
||||||
id: item.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
logger.info(`Deleted revision ${item.id} from note ${item.userId}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
})
|
||||||
|
|
||||||
cleanup()
|
|
||||||
|
|
|
@ -1,20 +1,115 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
const { spawnSync } = require('child_process')
|
|
||||||
const path = require('path')
|
const logger = require('../../lib/logger')
|
||||||
|
const models = require('../../lib/models')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
cleanup: async function () {
|
||||||
|
logger.info('Cleaning up notes that should already have been removed. Sorry.')
|
||||||
|
await models.Note.findAll({
|
||||||
|
include: [{
|
||||||
|
model: models.User,
|
||||||
|
as: 'owner',
|
||||||
|
attributes: ['id']
|
||||||
|
}],
|
||||||
|
attributes: ['id', 'ownerId']
|
||||||
|
}).then(async function (notes) {
|
||||||
|
for (let i = 0, noteCount = notes.length; i < noteCount; i++) {
|
||||||
|
const item = notes[i]
|
||||||
|
if (item.ownerId != null && !item.owner) {
|
||||||
|
await models.Note.destroy({
|
||||||
|
where: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await models.Revision.destroy({
|
||||||
|
where: {
|
||||||
|
noteId: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await models.Author.destroy({
|
||||||
|
where: {
|
||||||
|
noteId: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
logger.info(`Deleted note ${item.id} from user ${item.ownerId}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await models.Author.findAll({
|
||||||
|
include: [{
|
||||||
|
model: models.User,
|
||||||
|
as: 'user',
|
||||||
|
attributes: ['id']
|
||||||
|
}],
|
||||||
|
attributes: ['id', 'userId']
|
||||||
|
}).then(async function (authors) {
|
||||||
|
for (let i = 0, authorCount = authors.length; i < authorCount; i++) {
|
||||||
|
const item = authors[i]
|
||||||
|
if (item.userId != null && !item.user) {
|
||||||
|
await models.Author.destroy({
|
||||||
|
where: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
logger.info(`Deleted authorship ${item.id} from user ${item.userId}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await models.Author.findAll({
|
||||||
|
include: [{
|
||||||
|
model: models.Note,
|
||||||
|
as: 'note',
|
||||||
|
attributes: ['id']
|
||||||
|
}],
|
||||||
|
attributes: ['id', 'noteId']
|
||||||
|
}).then(async function (authors) {
|
||||||
|
for (let i = 0, authorCount = authors.length; i < authorCount; i++) {
|
||||||
|
const item = authors[i]
|
||||||
|
if (item.noteId != null && !item.note) {
|
||||||
|
await models.Author.destroy({
|
||||||
|
where: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
logger.info(`Deleted authorship ${item.id} from note ${item.noteId}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await models.Revision.findAll({
|
||||||
|
include: [{
|
||||||
|
model: models.Note,
|
||||||
|
as: 'note',
|
||||||
|
attributes: ['id']
|
||||||
|
}],
|
||||||
|
attributes: ['id', 'noteId']
|
||||||
|
}).then(async function (revisions) {
|
||||||
|
for (let i = 0, revisionCount = revisions.length; i < revisionCount; i++) {
|
||||||
|
const item = revisions[i]
|
||||||
|
if (item.noteId != null && !item.note) {
|
||||||
|
await models.Revision.destroy({
|
||||||
|
where: {
|
||||||
|
id: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
logger.info(`Deleted revision ${item.id} from note ${item.userId}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
up: function (queryInterface, Sequelize) {
|
up: function (queryInterface, Sequelize) {
|
||||||
const cleanup = spawnSync(process.argv[0], ['./bin/cleanup'], { cwd: path.resolve(__dirname, '../../') })
|
return this.cleanup().then(function () {
|
||||||
if (cleanup.status !== 0) {
|
return queryInterface.addConstraint('Notes', ['ownerId'], {
|
||||||
throw new Error('Unable to cleanup')
|
type: 'foreign key',
|
||||||
}
|
name: 'Notes_owner_fkey',
|
||||||
return queryInterface.addConstraint('Notes', ['ownerId'], {
|
references: {
|
||||||
type: 'foreign key',
|
table: 'Users',
|
||||||
name: 'Notes_owner_fkey',
|
field: 'id'
|
||||||
references: {
|
},
|
||||||
table: 'Users',
|
onDelete: 'cascade'
|
||||||
field: 'id'
|
})
|
||||||
},
|
|
||||||
onDelete: 'cascade'
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return queryInterface.addConstraint('Revisions', ['noteId'], {
|
return queryInterface.addConstraint('Revisions', ['noteId'], {
|
||||||
type: 'foreign key',
|
type: 'foreign key',
|
||||||
|
|
Loading…
Reference in a new issue