in src/blob/persistence/SqlBlobMetadataStore.ts [1912:2083]
public async deleteBlob(
context: Context,
account: string,
container: string,
blob: string,
options: Models.BlobDeleteMethodOptionalParams
): Promise<void> {
await this.sequelize.transaction(async (t) => {
await this.assertContainerExists(context, account, container, t);
const blobFindResult = await BlobsModel.findOne({
where: {
accountName: account,
containerName: container,
blobName: blob,
snapshot: options.snapshot === undefined ? "" : options.snapshot,
deleting: 0,
isCommitted: true // TODO: Support deleting uncommitted block blob
},
transaction: t
});
validateWriteConditions(
context,
options.modifiedAccessConditions,
blobFindResult
? this.convertDbModelToBlobModel(blobFindResult) // TODO: Reduce double convert
: undefined
);
if (blobFindResult === null || blobFindResult === undefined) {
throw StorageErrorFactory.getBlobNotFound(context.contextId);
}
const blobModel = this.convertDbModelToBlobModel(blobFindResult);
const againstBaseBlob = blobModel.snapshot === "";
if (againstBaseBlob) {
LeaseFactory.createLeaseState(
new BlobLeaseAdapter(blobModel),
context
).validate(new BlobWriteLeaseValidator(options.leaseAccessConditions));
}
// Check bad requests
if (!againstBaseBlob && options.deleteSnapshots !== undefined) {
throw StorageErrorFactory.getInvalidOperation(
context.contextId,
"Invalid operation against a blob snapshot."
);
}
// Scenario: Delete base blob only
if (againstBaseBlob && options.deleteSnapshots === undefined) {
const count = await BlobsModel.count({
where: {
accountName: account,
containerName: container,
blobName: blob,
deleting: 0
},
transaction: t
});
if (count > 1) {
throw StorageErrorFactory.getSnapshotsPresent(context.contextId!);
} else {
await BlobsModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob
},
transaction: t
}
);
await BlocksModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob
},
transaction: t
}
);
}
}
// Scenario: Delete one snapshot only
if (!againstBaseBlob) {
await BlobsModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob,
snapshot: blobModel.snapshot
},
transaction: t
}
);
}
// Scenario: Delete base blob and snapshots
if (
againstBaseBlob &&
options.deleteSnapshots === Models.DeleteSnapshotsOptionType.Include
) {
await BlobsModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob
},
transaction: t
}
);
await BlocksModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob
},
transaction: t
}
);
}
// Scenario: Delete all snapshots only
if (
againstBaseBlob &&
options.deleteSnapshots === Models.DeleteSnapshotsOptionType.Only
) {
await BlobsModel.update(
{
deleting: literal("deleting + 1")
},
{
where: {
accountName: account,
containerName: container,
blobName: blob,
snapshot: { [Op.gt]: "" }
},
transaction: t
}
);
}
});
}