Removing attachments when row is deleted (always, need to restrict if app is deployed).

This commit is contained in:
mike12345567 2022-01-06 17:59:29 +00:00
parent 657f55f0da
commit f1981220af
4 changed files with 66 additions and 0 deletions

View File

@ -206,6 +206,34 @@ exports.retrieveToTmp = async (bucketName, filepath) => {
return outputPath return outputPath
} }
/**
* Delete a single file.
*/
exports.deleteFile = async (bucketName, filepath) => {
const objectStore = exports.ObjectStore(bucketName)
await exports.makeSureBucketExists(objectStore, bucketName)
const params = {
Bucket: bucketName,
Key: filepath,
}
return objectStore.deleteObject(params)
}
exports.deleteFiles = async (bucketName, filepaths) => {
const objectStore = exports.ObjectStore(bucketName)
await exports.makeSureBucketExists(objectStore, bucketName)
const params = {
Bucket: bucketName,
Delete: {
Objects: filepaths.map(path => ({ Key: path })),
},
}
return objectStore.deleteObjects(params).promise()
}
/**
* Delete a path, including everything within.
*/
exports.deleteFolder = async (bucketName, folder) => { exports.deleteFolder = async (bucketName, folder) => {
bucketName = sanitizeBucket(bucketName) bucketName = sanitizeBucket(bucketName)
folder = sanitizeKey(folder) folder = sanitizeKey(folder)

View File

@ -11,6 +11,7 @@ const {
inputProcessing, inputProcessing,
outputProcessing, outputProcessing,
processAutoColumn, processAutoColumn,
cleanupAttachments,
} = require("../../../utilities/rowProcessor") } = require("../../../utilities/rowProcessor")
const { FieldTypes } = require("../../../constants") const { FieldTypes } = require("../../../constants")
const { isEqual } = require("lodash") const { isEqual } = require("lodash")
@ -295,6 +296,8 @@ exports.destroy = async function (ctx) {
row, row,
tableId: row.tableId, tableId: row.tableId,
}) })
// remove any attachments that were on the row from object storage
await cleanupAttachments(appId, table, { row })
let response let response
if (ctx.params.tableId === InternalTables.USER_METADATA) { if (ctx.params.tableId === InternalTables.USER_METADATA) {
@ -341,6 +344,8 @@ exports.bulkDestroy = async ctx => {
} else { } else {
await db.bulkDocs(rows.map(row => ({ ...row, _deleted: true }))) await db.bulkDocs(rows.map(row => ({ ...row, _deleted: true })))
} }
// remove any attachments that were on the rows from object storage
await cleanupAttachments(appId, table, { rows })
await Promise.all(updates) await Promise.all(updates)
return { response: { ok: true }, rows } return { response: { ok: true }, rows }
} }

View File

@ -2,6 +2,7 @@ const {
ObjectStore, ObjectStore,
makeSureBucketExists, makeSureBucketExists,
upload, upload,
deleteFiles,
streamUpload, streamUpload,
retrieve, retrieve,
retrieveToTmp, retrieveToTmp,
@ -28,3 +29,4 @@ exports.retrieveToTmp = retrieveToTmp
exports.deleteFolder = deleteFolder exports.deleteFolder = deleteFolder
exports.uploadDirectory = uploadDirectory exports.uploadDirectory = uploadDirectory
exports.downloadTarball = downloadTarball exports.downloadTarball = downloadTarball
exports.deleteFiles = deleteFiles

View File

@ -3,6 +3,8 @@ const { cloneDeep } = require("lodash/fp")
const { FieldTypes, AutoFieldSubTypes } = require("../../constants") const { FieldTypes, AutoFieldSubTypes } = require("../../constants")
const { attachmentsRelativeURL } = require("../index") const { attachmentsRelativeURL } = require("../index")
const { processFormulas } = require("./utils") const { processFormulas } = require("./utils")
const { deleteFiles } = require("../../utilities/fileSystem/utilities")
const { ObjectStoreBuckets } = require("../../constants")
const BASE_AUTO_ID = 1 const BASE_AUTO_ID = 1
@ -272,3 +274,32 @@ exports.outputProcessing = async (
} }
return wasArray ? enriched : enriched[0] return wasArray ? enriched : enriched[0]
} }
/**
* Clean up any attachments that were attached to a row.
* @param {string} appId The ID of the app from which a row is being deleted.
* @param {object} table The table from which a row is being removed.
* @param {any} row optional - the row being removed.
* @param {any} rows optional - if multiple rows being deleted can do this in bulk.
* @return {Promise<void>} When all attachments have been removed this will return.
*/
exports.cleanupAttachments = async (appId, table, {row, rows}) => {
// TODO: check app ID version
let files = []
function addFiles(row, key) {
if (row[key]) {
files = files.concat(row[key].map(attachment => attachment.key))
}
}
for (let [key, schema] of Object.entries(table.schema)) {
if (schema.type !== FieldTypes.ATTACHMENT) {
continue
}
if (row) {
addFiles(row, key)
} else if (rows) {
rows.forEach(row => addFiles(row, key))
}
}
return deleteFiles(ObjectStoreBuckets.APPS, files)
}