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>
		
			
				
	
	
		
			164 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict'
 | |
| 
 | |
| const logger = require('../../lib/logger')
 | |
| const models = require('../../lib/models')
 | |
| 
 | |
| 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) {
 | |
|     return this.cleanup().then(function () {
 | |
|       return queryInterface.addConstraint('Notes', ['ownerId'], {
 | |
|         type: 'foreign key',
 | |
|         name: 'Notes_owner_fkey',
 | |
|         references: {
 | |
|           table: 'Users',
 | |
|           field: 'id'
 | |
|         },
 | |
|         onDelete: 'cascade'
 | |
|       })
 | |
|     }).then(function () {
 | |
|       return queryInterface.addConstraint('Revisions', ['noteId'], {
 | |
|         type: 'foreign key',
 | |
|         name: 'Revisions_note_fkey',
 | |
|         references: {
 | |
|           table: 'Notes',
 | |
|           field: 'id'
 | |
|         },
 | |
|         onDelete: 'cascade'
 | |
|       })
 | |
|     }).then(function () {
 | |
|       return queryInterface.addConstraint('Authors', ['noteId'], {
 | |
|         type: 'foreign key',
 | |
|         name: 'Author_note_fkey',
 | |
|         references: {
 | |
|           table: 'Notes',
 | |
|           field: 'id'
 | |
|         },
 | |
|         onDelete: 'cascade'
 | |
|       })
 | |
|     }).then(function () {
 | |
|       return queryInterface.addConstraint('Authors', ['userId'], {
 | |
|         type: 'foreign key',
 | |
|         name: 'Author_user_fkey',
 | |
|         references: {
 | |
|           table: 'Users',
 | |
|           field: 'id'
 | |
|         },
 | |
|         onDelete: 'cascade'
 | |
|       })
 | |
|     }).catch(function (error) {
 | |
|       if (error.message.toLowerCase().includes('duplicate key on write or update')) {
 | |
|         // eslint-disable-next-line no-console
 | |
|         console.log('Migration has already run… ignoring.')
 | |
|       } else {
 | |
|         throw error
 | |
|       }
 | |
|     })
 | |
|   },
 | |
| 
 | |
|   down: function (queryInterface, Sequelize) {
 | |
|     return queryInterface.removeConstraint('Notes', 'Notes_owner_fkey')
 | |
|       .then(function () {
 | |
|         return queryInterface.removeConstraint('Revisions', 'Revisions_note_fkey')
 | |
|       }).then(function () {
 | |
|         return queryInterface.removeConstraint('Authors', 'Author_note_fkey')
 | |
|       }).then(function () {
 | |
|         return queryInterface.removeConstraint('Authors', 'Author_user_fkey')
 | |
|       })
 | |
|   }
 | |
| }
 |