Improved attachment repository logic.
This commit is contained in:
parent
952d149825
commit
6b563003ec
|
@ -62,6 +62,7 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
|
||||||
SELECT DISTINCT ON (account.id) account.*, ahi.timestamp AS _
|
SELECT DISTINCT ON (account.id) account.*, ahi.timestamp AS _
|
||||||
FROM account
|
FROM account
|
||||||
LEFT OUTER JOIN account_history_item ahi ON ahi.account_id = account.id
|
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""",
|
ORDER BY ahi.timestamp DESC, account.created_at DESC""",
|
||||||
JdbcAccountRepository::parseAccount
|
JdbcAccountRepository::parseAccount
|
||||||
);
|
);
|
||||||
|
@ -84,7 +85,7 @@ public record JdbcAccountRepository(Connection conn, Path contentDir) implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateName(long id, String name) {
|
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
|
@Override
|
||||||
|
|
|
@ -58,15 +58,9 @@ public record JdbcAttachmentRepository(Connection conn, Path contentDir) impleme
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(long attachmentId) {
|
public void deleteById(long attachmentId) {
|
||||||
// First get it and try to delete the stored file.
|
|
||||||
var optionalAttachment = findById(attachmentId);
|
var optionalAttachment = findById(attachmentId);
|
||||||
if (optionalAttachment.isPresent()) {
|
if (optionalAttachment.isPresent()) {
|
||||||
try {
|
deleteFileOnDisk(optionalAttachment.get());
|
||||||
Files.delete(optionalAttachment.get().getPath(contentDir));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
// TODO: Add some sort of persistent error logging.
|
|
||||||
}
|
|
||||||
DbUtil.updateOne(conn, "DELETE FROM attachment WHERE id = ?", List.of(attachmentId));
|
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
|
JdbcAttachmentRepository::parseAttachment
|
||||||
);
|
);
|
||||||
for (Attachment orphan : orphans) {
|
for (Attachment orphan : orphans) {
|
||||||
|
deleteFileOnDisk(orphan);
|
||||||
DbUtil.updateOne(
|
DbUtil.updateOne(
|
||||||
conn,
|
conn,
|
||||||
"DELETE FROM attachment WHERE id = ?",
|
"DELETE FROM attachment WHERE id = ?",
|
||||||
List.of(orphan.id)
|
List.of(orphan.id)
|
||||||
);
|
);
|
||||||
Path filePath = orphan.getPath(contentDir);
|
log.debug("Deleted orphan attachment with id {} at {}.", orphan.id, 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);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -120,4 +103,27 @@ public record JdbcAttachmentRepository(Connection conn, Path contentDir) impleme
|
||||||
rs.getString("content_type")
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue