mirror of https://github.com/usememos/memos.git
fix: delete unused attachments by using filter
This commit is contained in:
parent
4b110d0d38
commit
d68ca84832
|
|
@ -207,6 +207,17 @@ func (r *renderer) renderScalarComparison(field Field, op ComparisonOperator, ri
|
|||
}
|
||||
|
||||
columnExpr := field.columnExpr(r.dialect)
|
||||
if lit == nil {
|
||||
switch op {
|
||||
case CompareEq:
|
||||
return renderResult{sql: fmt.Sprintf("%s IS NULL", columnExpr)}, nil
|
||||
case CompareNeq:
|
||||
return renderResult{sql: fmt.Sprintf("%s IS NOT NULL", columnExpr)}, nil
|
||||
default:
|
||||
return renderResult{}, errors.Errorf("operator %s not supported for null comparison", op)
|
||||
}
|
||||
}
|
||||
|
||||
placeholder := ""
|
||||
switch field.Type {
|
||||
case FieldTypeString:
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ func NewAttachmentSchema() Schema {
|
|||
cel.Variable("filename", cel.StringType),
|
||||
cel.Variable("mime_type", cel.StringType),
|
||||
cel.Variable("create_time", cel.IntType),
|
||||
cel.Variable("memo_id", cel.IntType),
|
||||
cel.Variable("memo_id", cel.AnyType),
|
||||
nowFunction,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,9 +328,18 @@ func TestAttachmentFilterNullMemoId(t *testing.T) {
|
|||
tc.CreateAttachment(NewAttachmentBuilder(tc.CreatorID).Filename("with_memo.png").MimeType("image/png").MemoID(&memo.ID))
|
||||
tc.CreateAttachment(NewAttachmentBuilder(tc.CreatorID).Filename("no_memo.png").MimeType("image/png"))
|
||||
|
||||
attachments := tc.ListWithFilter(`memo_id == ` + formatInt32(memo.ID))
|
||||
// Test: memo_id == null
|
||||
attachments := tc.ListWithFilter(`memo_id == null`)
|
||||
require.Len(t, attachments, 1)
|
||||
require.Equal(t, "no_memo.png", attachments[0].Filename)
|
||||
require.Nil(t, attachments[0].MemoID)
|
||||
|
||||
// Test: memo_id != null
|
||||
attachments = tc.ListWithFilter(`memo_id != null`)
|
||||
require.Len(t, attachments, 1)
|
||||
require.Equal(t, "with_memo.png", attachments[0].Filename)
|
||||
require.NotNil(t, attachments[0].MemoID)
|
||||
require.Equal(t, memo.ID, *attachments[0].MemoID)
|
||||
}
|
||||
|
||||
func TestAttachmentFilterEmptyFilename(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,19 @@ const Attachments = () => {
|
|||
// Delete all unused attachments
|
||||
const handleDeleteUnusedAttachments = useCallback(async () => {
|
||||
try {
|
||||
await Promise.all(unusedAttachments.map((attachment) => deleteAttachment(attachment.name)));
|
||||
let allUnusedAttachments: Attachment[] = [];
|
||||
let nextPageToken = "";
|
||||
do {
|
||||
const response = await attachmentServiceClient.listAttachments({
|
||||
pageSize: 1000,
|
||||
pageToken: nextPageToken,
|
||||
filter: "memo_id == null",
|
||||
});
|
||||
allUnusedAttachments = [...allUnusedAttachments, ...response.attachments];
|
||||
nextPageToken = response.nextPageToken;
|
||||
} while (nextPageToken);
|
||||
|
||||
await Promise.all(allUnusedAttachments.map((attachment) => deleteAttachment(attachment.name)));
|
||||
toast.success(t("resource.delete-all-unused-success"));
|
||||
} catch (error) {
|
||||
handleError(error, toast.error, {
|
||||
|
|
@ -166,7 +178,7 @@ const Attachments = () => {
|
|||
} finally {
|
||||
await handleRefetch();
|
||||
}
|
||||
}, [unusedAttachments, t, handleRefetch, deleteAttachment]);
|
||||
}, [t, handleRefetch, deleteAttachment]);
|
||||
|
||||
// Handle search input change
|
||||
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue