Removing attachments when row is deleted (always, need to restrict if app is deployed).
This commit is contained in:
parent
657f55f0da
commit
f1981220af
|
@ -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)
|
||||||
|
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue