Browse Source

fix: process attachments only if provided

nc-feat/attachment-clean-up
mertmit 4 months ago
parent
commit
e98b8f29a5
  1. 210
      packages/nocodb/src/db/BaseModelSqlv2.ts

210
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -9271,121 +9271,129 @@ class BaseModelSqlv2 {
} }
} }
if (column.uidt === UITypes.Attachment) { if (column.uidt === UITypes.Attachment) {
if (data && data[column.column_name]) { if (column.column_name in data) {
try { if (data && data[column.column_name]) {
if (typeof data[column.column_name] === 'string') { try {
data[column.column_name] = JSON.parse(data[column.column_name]); if (typeof data[column.column_name] === 'string') {
data[column.column_name] = JSON.parse(data[column.column_name]);
}
} catch (e) {
NcError.invalidAttachmentJson(data[column.column_name]);
} }
} catch (e) {
NcError.invalidAttachmentJson(data[column.column_name]);
} }
}
if (oldData && oldData[column.column_name]) { if (oldData && oldData[column.column_name]) {
try { try {
if (typeof oldData[column.column_name] === 'string') { if (typeof oldData[column.column_name] === 'string') {
oldData[column.column_name] = JSON.parse( oldData[column.column_name] = JSON.parse(
oldData[column.column_name], oldData[column.column_name],
); );
} }
} catch (e) {} } catch (e) {}
} }
const regenerateIds = []; const regenerateIds = [];
if (!isInsertData) { if (!isInsertData) {
const oldAttachmentMap = new Map< const oldAttachmentMap = new Map<
string, string,
{ url?: string; path?: string } { url?: string; path?: string }
>( >(
oldData && oldData &&
oldData[column.column_name] && oldData[column.column_name] &&
Array.isArray(oldData[column.column_name]) Array.isArray(oldData[column.column_name])
? oldData[column.column_name].filter((att) => att.id).map((att) => [att.id, att]) ? oldData[column.column_name]
: [], .filter((att) => att.id)
); .map((att) => [att.id, att])
: [],
);
const newAttachmentMap = new Map< const newAttachmentMap = new Map<
string, string,
{ url?: string; path?: string } { url?: string; path?: string }
>( >(
data[column.column_name] && Array.isArray(data[column.column_name]) data[column.column_name] &&
? data[column.column_name].filter((att) => att.id).map((att) => [att.id, att]) Array.isArray(data[column.column_name])
: [], ? data[column.column_name]
); .filter((att) => att.id)
.map((att) => [att.id, att])
: [],
);
for (const [oldId, oldAttachment] of oldAttachmentMap) { for (const [oldId, oldAttachment] of oldAttachmentMap) {
if (!newAttachmentMap.has(oldId)) { if (!newAttachmentMap.has(oldId)) {
await FileReference.delete(this.context, oldId); await FileReference.delete(this.context, oldId);
} else if ( } else if (
(oldAttachment.url && (oldAttachment.url &&
oldAttachment.url !== newAttachmentMap.get(oldId).url) || oldAttachment.url !== newAttachmentMap.get(oldId).url) ||
(oldAttachment.path && (oldAttachment.path &&
oldAttachment.path !== newAttachmentMap.get(oldId).path) oldAttachment.path !== newAttachmentMap.get(oldId).path)
) { ) {
await FileReference.delete(this.context, oldId); await FileReference.delete(this.context, oldId);
regenerateIds.push(oldId); regenerateIds.push(oldId);
}
} }
}
for (const [newId, newAttachment] of newAttachmentMap) { for (const [newId, newAttachment] of newAttachmentMap) {
if (!oldAttachmentMap.has(newId)) { if (!oldAttachmentMap.has(newId)) {
regenerateIds.push(newId); regenerateIds.push(newId);
} else if ( } else if (
(newAttachment.url && (newAttachment.url &&
newAttachment.url !== oldAttachmentMap.get(newId).url) || newAttachment.url !== oldAttachmentMap.get(newId).url) ||
(newAttachment.path && (newAttachment.path &&
newAttachment.path !== oldAttachmentMap.get(newId).path) newAttachment.path !== oldAttachmentMap.get(newId).path)
) { ) {
regenerateIds.push(newId); regenerateIds.push(newId);
}
} }
} }
}
const sanitizedAttachments = []; const sanitizedAttachments = [];
if (Array.isArray(data[column.column_name])) { if (Array.isArray(data[column.column_name])) {
for (const attachment of data[column.column_name]) { for (const attachment of data[column.column_name]) {
if (!('url' in attachment) && !('path' in attachment)) { if (!('url' in attachment) && !('path' in attachment)) {
NcError.unprocessableEntity( NcError.unprocessableEntity(
'Attachment object must contain either url or path', 'Attachment object must contain either url or path',
); );
} }
const sanitizedAttachment = extractProps(attachment, [ const sanitizedAttachment = extractProps(attachment, [
'id', 'id',
'url', 'url',
'path', 'path',
'title', 'title',
'mimetype', 'mimetype',
'size', 'size',
'icon', 'icon',
'width', 'width',
'height', 'height',
]); ]);
if (
isInsertData ||
!sanitizedAttachment.id ||
regenerateIds.includes(sanitizedAttachment.id)
) {
sanitizedAttachment.id = await FileReference.insert(
this.context,
{
file_url: sanitizedAttachment.url ?? sanitizedAttachment.path,
file_size: sanitizedAttachment.size,
fk_user_id: cookie?.user?.id,
fk_model_id: this.model.id,
fk_column_id: column.id,
},
);
}
sanitizedAttachments.push(sanitizedAttachment); if (
isInsertData ||
!sanitizedAttachment.id ||
regenerateIds.includes(sanitizedAttachment.id)
) {
sanitizedAttachment.id = await FileReference.insert(
this.context,
{
file_url:
sanitizedAttachment.url ?? sanitizedAttachment.path,
file_size: sanitizedAttachment.size,
fk_user_id: cookie?.user?.id,
fk_model_id: this.model.id,
fk_column_id: column.id,
},
);
}
sanitizedAttachments.push(sanitizedAttachment);
}
} }
}
data[column.column_name] = sanitizedAttachments.length data[column.column_name] = sanitizedAttachments.length
? JSON.stringify(sanitizedAttachments) ? JSON.stringify(sanitizedAttachments)
: null; : null;
}
} else if ( } else if (
[UITypes.User, UITypes.CreatedBy, UITypes.LastModifiedBy].includes( [UITypes.User, UITypes.CreatedBy, UITypes.LastModifiedBy].includes(
column.uidt, column.uidt,

Loading…
Cancel
Save