Use Bucket.deleteFiles to delete directory contents, instead of iterating

This commit is contained in:
Simon Detheridge 2020-03-05 14:12:15 +00:00
parent 460dd96b17
commit eb93ae4b10
2 changed files with 17 additions and 75 deletions

View file

@ -191,41 +191,29 @@ async function deleteFile(bucketName, key) {
}
async function deleteDirectory(bucketName, key) {
let files
if (!key.match(/^[a-z0-9_-]+/i)) {
throw new NotFoundError({
message: 'deleteDirectoryKey is invalid or missing',
info: { bucketName, key }
})
}
try {
const [response] = await storage
await storage
.bucket(bucketName)
.getFiles({ directory: key })
files = response
.deleteFiles({ directory: key, force: true })
} catch (err) {
const error = PersistorHelper.wrapError(
err,
'failed to list objects in GCS',
'failed to delete directory in GCS',
{ bucketName, key },
ReadError
WriteError
)
if (error instanceof NotFoundError) {
return
}
throw error
}
for (const index in files) {
try {
await files[index].delete()
} catch (err) {
const error = PersistorHelper.wrapError(
err,
'failed to delete object in GCS',
{ bucketName, key },
WriteError
)
if (!(error instanceof NotFoundError)) {
throw error
}
}
}
}
async function directorySize(bucketName, key) {

View file

@ -84,7 +84,8 @@ describe('GcsPersistorTests', function() {
GcsBucket = {
file: sinon.stub().returns(GcsFile),
getFiles: sinon.stub().resolves([files])
getFiles: sinon.stub().resolves([files]),
deleteFiles: sinon.stub().resolves()
}
Storage = class {
@ -516,67 +517,20 @@ describe('GcsPersistorTests', function() {
return GcsPersistor.promises.deleteDirectory(bucket, key)
})
it('should list the objects in the directory', function() {
it('should delete the objects in the directory', function() {
expect(Storage.prototype.bucket).to.have.been.calledWith(bucket)
expect(GcsBucket.getFiles).to.have.been.calledWith({
directory: key
expect(GcsBucket.deleteFiles).to.have.been.calledWith({
directory: key,
force: true
})
})
it('should delete the objects', function() {
expect(files[0].delete).to.have.been.called
expect(files[1].delete).to.have.been.called
})
})
describe('when there are no files', function() {
beforeEach(async function() {
GcsBucket.getFiles.resolves([[]])
return GcsPersistor.promises.deleteDirectory(bucket, key)
})
it('should list the objects in the directory', function() {
expect(GcsBucket.getFiles).to.have.been.calledWith({
directory: key
})
})
it('should not try to delete any objects', function() {
expect(files[0].delete).not.to.have.been.called
expect(files[1].delete).not.to.have.been.called
})
})
describe('when there is an error listing the objects', function() {
let error
beforeEach(async function() {
GcsBucket.getFiles = sinon.stub().rejects(genericError)
try {
await GcsPersistor.promises.deleteDirectory(bucket, key)
} catch (err) {
error = err
}
})
it('should generate a ReadError', function() {
expect(error).to.be.an.instanceOf(Errors.ReadError)
})
it('should wrap the error', function() {
expect(error.cause).to.equal(genericError)
})
it('should not try to delete any objects', function() {
expect(files[0].delete).not.to.have.been.called
})
})
describe('when there is an error deleting the objects', function() {
let error
beforeEach(async function() {
files[0].delete = sinon.stub().rejects(genericError)
GcsBucket.deleteFiles = sinon.stub().rejects(genericError)
try {
await GcsPersistor.promises.deleteDirectory(bucket, key)
} catch (err) {