Improved attachment repository logic.

This commit is contained in:
Andrew Lalis 2024-01-10 18:10:43 -05:00
parent 952d149825
commit 6b563003ec
2 changed files with 28 additions and 21 deletions

View File

@ -62,6 +62,7 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
SELECT DISTINCT ON (account.id) account.*, ahi.timestamp AS _
FROM account
LEFT OUTER JOIN account_history_item ahi ON ahi.account_id = account.id
WHERE NOT account.archived
ORDER BY ahi.timestamp DESC, account.created_at DESC""",
JdbcAccountRepository::parseAccount
);
@ -84,7 +85,7 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
@Override
public void updateName(long id, String name) {
DbUtil.updateOne(conn, "UPDATE account SET name = ? WHERE id = ?", List.of(name, id));
DbUtil.updateOne(conn, "UPDATE account SET name = ? WHERE id = ? AND NOT archived", List.of(name, id));
}
@Override

View File

@ -58,15 +58,9 @@ public record JdbcAttachmentRepository(Connection conn, Path contentDir) impleme
@Override
public void deleteById(long attachmentId) {
// First get it and try to delete the stored file.
var optionalAttachment = findById(attachmentId);
if (optionalAttachment.isPresent()) {
try {
Files.delete(optionalAttachment.get().getPath(contentDir));
} catch (IOException e) {
e.printStackTrace(System.err);
// TODO: Add some sort of persistent error logging.
}
deleteFileOnDisk(optionalAttachment.get());
DbUtil.updateOne(conn, "DELETE FROM attachment WHERE id = ?", List.of(attachmentId));
}
}
@ -84,24 +78,13 @@ public record JdbcAttachmentRepository(Connection conn, Path contentDir) impleme
JdbcAttachmentRepository::parseAttachment
);
for (Attachment orphan : orphans) {
deleteFileOnDisk(orphan);
DbUtil.updateOne(
conn,
"DELETE FROM attachment WHERE id = ?",
List.of(orphan.id)
);
Path filePath = orphan.getPath(contentDir);
try {
Files.deleteIfExists(filePath);
Path parentDir = filePath.getParent();
try (var filesRemaining = Files.list(parentDir)) {
if (filesRemaining.findAny().isEmpty()) {
Files.delete(parentDir);
}
}
} catch (IOException e) {
log.warn("Failed to delete attachment at " + filePath + ".", e);
}
log.debug("Deleted orphan attachment with id {} at {}.", orphan.id, filePath);
log.debug("Deleted orphan attachment with id {} at {}.", orphan.id, orphan.getPath(contentDir));
}
});
}
@ -120,4 +103,27 @@ public record JdbcAttachmentRepository(Connection conn, Path contentDir) impleme
rs.getString("content_type")
);
}
/**
* Internal method that's used when deleting attachments, to also remove the
* actual file contents from the Perfin profile's content directory. This
* will delete the file, and also remove the parent directory if it's empty.
* @param attachment The attachment to delete the file for.
*/
private void deleteFileOnDisk(Attachment attachment) {
Path filePath = attachment.getPath(contentDir);
if (Files.exists(filePath)) {
try {
Files.delete(filePath);
// Try and delete the parent directory if it's empty now.
try (var files = Files.list(filePath.getParent())) {
if (files.findAny().isEmpty()) {
Files.delete(filePath.getParent());
}
}
} catch (IOException e) {
log.warn("Failed to delete file {} for deleted attachment {}.", filePath, attachment.id);
}
}
}
}