mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
renamed attachment's parentId to more fitting ownerId
This commit is contained in:
parent
ca41806bc2
commit
d475346a09
@ -1,7 +1,7 @@
|
|||||||
CREATE TABLE IF NOT EXISTS "attachments"
|
CREATE TABLE IF NOT EXISTS "attachments"
|
||||||
(
|
(
|
||||||
attachmentId TEXT not null primary key,
|
attachmentId TEXT not null primary key,
|
||||||
parentId TEXT not null,
|
ownerId TEXT not null,
|
||||||
role TEXT not null,
|
role TEXT not null,
|
||||||
mime TEXT not null,
|
mime TEXT not null,
|
||||||
title TEXT not null,
|
title TEXT not null,
|
||||||
@ -14,8 +14,8 @@ CREATE TABLE IF NOT EXISTS "attachments"
|
|||||||
isDeleted INT not null,
|
isDeleted INT not null,
|
||||||
deleteId TEXT DEFAULT NULL);
|
deleteId TEXT DEFAULT NULL);
|
||||||
|
|
||||||
CREATE INDEX IDX_attachments_parentId_role
|
CREATE INDEX IDX_attachments_ownerId_role
|
||||||
on attachments (parentId, role);
|
on attachments (ownerId, role);
|
||||||
|
|
||||||
CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince
|
CREATE INDEX IDX_attachments_utcDateScheduledForErasureSince
|
||||||
on attachments (utcDateScheduledForErasureSince);
|
on attachments (utcDateScheduledForErasureSince);
|
||||||
|
@ -114,7 +114,7 @@ CREATE TABLE IF NOT EXISTS "blobs" (
|
|||||||
CREATE TABLE IF NOT EXISTS "attachments"
|
CREATE TABLE IF NOT EXISTS "attachments"
|
||||||
(
|
(
|
||||||
attachmentId TEXT not null primary key,
|
attachmentId TEXT not null primary key,
|
||||||
parentId TEXT not null,
|
ownerId TEXT not null,
|
||||||
role TEXT not null,
|
role TEXT not null,
|
||||||
mime TEXT not null,
|
mime TEXT not null,
|
||||||
title TEXT not null,
|
title TEXT not null,
|
||||||
@ -126,5 +126,5 @@ CREATE TABLE IF NOT EXISTS "attachments"
|
|||||||
utcDateScheduledForErasureSince TEXT DEFAULT NULL,
|
utcDateScheduledForErasureSince TEXT DEFAULT NULL,
|
||||||
isDeleted INT not null,
|
isDeleted INT not null,
|
||||||
deleteId TEXT DEFAULT NULL);
|
deleteId TEXT DEFAULT NULL);
|
||||||
CREATE INDEX IDX_attachments_parentId_role
|
CREATE INDEX IDX_attachments_ownerId_role
|
||||||
on attachments (parentId, role);
|
on attachments (ownerId, role);
|
||||||
|
@ -20,14 +20,14 @@ const attachmentRoleToNoteTypeMapping = {
|
|||||||
class BAttachment extends AbstractBeccaEntity {
|
class BAttachment extends AbstractBeccaEntity {
|
||||||
static get entityName() { return "attachments"; }
|
static get entityName() { return "attachments"; }
|
||||||
static get primaryKeyName() { return "attachmentId"; }
|
static get primaryKeyName() { return "attachmentId"; }
|
||||||
static get hashedProperties() { return ["attachmentId", "parentId", "role", "mime", "title", "blobId",
|
static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId",
|
||||||
"utcDateScheduledForErasureSince", "utcDateModified"]; }
|
"utcDateScheduledForErasureSince", "utcDateModified"]; }
|
||||||
|
|
||||||
constructor(row) {
|
constructor(row) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (!row.parentId?.trim()) {
|
if (!row.ownerId?.trim()) {
|
||||||
throw new Error("'parentId' must be given to initialize a Attachment entity");
|
throw new Error("'ownerId' must be given to initialize a Attachment entity");
|
||||||
} else if (!row.role?.trim()) {
|
} else if (!row.role?.trim()) {
|
||||||
throw new Error("'role' must be given to initialize a Attachment entity");
|
throw new Error("'role' must be given to initialize a Attachment entity");
|
||||||
} else if (!row.mime?.trim()) {
|
} else if (!row.mime?.trim()) {
|
||||||
@ -39,7 +39,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
this.attachmentId = row.attachmentId;
|
this.attachmentId = row.attachmentId;
|
||||||
/** @type {string} either noteId or revisionId to which this attachment belongs */
|
/** @type {string} either noteId or revisionId to which this attachment belongs */
|
||||||
this.parentId = row.parentId;
|
this.ownerId = row.ownerId;
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
this.role = row.role;
|
this.role = row.role;
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
@ -68,7 +68,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
/** @returns {BAttachment} */
|
/** @returns {BAttachment} */
|
||||||
copy() {
|
copy() {
|
||||||
return new BAttachment({
|
return new BAttachment({
|
||||||
parentId: this.parentId,
|
ownerId: this.ownerId,
|
||||||
role: this.role,
|
role: this.role,
|
||||||
mime: this.mime,
|
mime: this.mime,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
@ -79,7 +79,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
|
|
||||||
/** @returns {BNote} */
|
/** @returns {BNote} */
|
||||||
getNote() {
|
getNote() {
|
||||||
return this.becca.notes[this.parentId];
|
return this.becca.notes[this.ownerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {boolean} true if the note has string content (not binary) */
|
/** @returns {boolean} true if the note has string content (not binary) */
|
||||||
@ -148,7 +148,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
const noteService = require('../../services/notes');
|
const noteService = require('../../services/notes');
|
||||||
|
|
||||||
const { note, branch } = noteService.createNewNote({
|
const { note, branch } = noteService.createNewNote({
|
||||||
parentNoteId: this.parentId,
|
parentNoteId: this.ownerId,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
type: attachmentRoleToNoteTypeMapping[this.role],
|
type: attachmentRoleToNoteTypeMapping[this.role],
|
||||||
mime: this.mime,
|
mime: this.mime,
|
||||||
@ -189,7 +189,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
if (this.position === undefined || this.position === null) {
|
if (this.position === undefined || this.position === null) {
|
||||||
this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0)
|
this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0)
|
||||||
FROM attachments
|
FROM attachments
|
||||||
WHERE parentId = ?`, [this.noteId]);
|
WHERE ownerId = ?`, [this.noteId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dateModified = dateUtils.localNowDateTime();
|
this.dateModified = dateUtils.localNowDateTime();
|
||||||
@ -199,7 +199,7 @@ class BAttachment extends AbstractBeccaEntity {
|
|||||||
getPojo() {
|
getPojo() {
|
||||||
return {
|
return {
|
||||||
attachmentId: this.attachmentId,
|
attachmentId: this.attachmentId,
|
||||||
parentId: this.parentId,
|
ownerId: this.ownerId,
|
||||||
role: this.role,
|
role: this.role,
|
||||||
mime: this.mime,
|
mime: this.mime,
|
||||||
title: this.title,
|
title: this.title,
|
||||||
|
@ -1101,9 +1101,9 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
|
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
|
||||||
FROM attachments
|
FROM attachments
|
||||||
JOIN blobs USING (blobId)
|
JOIN blobs USING (blobId)
|
||||||
WHERE parentId = ? AND isDeleted = 0
|
WHERE ownerId = ? AND isDeleted = 0
|
||||||
ORDER BY position`
|
ORDER BY position`
|
||||||
: `SELECT * FROM attachments WHERE parentId = ? AND isDeleted = 0 ORDER BY position`;
|
: `SELECT * FROM attachments WHERE ownerId = ? AND isDeleted = 0 ORDER BY position`;
|
||||||
|
|
||||||
return sql.getRows(query, [this.noteId])
|
return sql.getRows(query, [this.noteId])
|
||||||
.map(row => new BAttachment(row));
|
.map(row => new BAttachment(row));
|
||||||
@ -1117,8 +1117,8 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
|
? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength
|
||||||
FROM attachments
|
FROM attachments
|
||||||
JOIN blobs USING (blobId)
|
JOIN blobs USING (blobId)
|
||||||
WHERE parentId = ? AND attachmentId = ? AND isDeleted = 0`
|
WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`
|
||||||
: `SELECT * FROM attachments WHERE parentId = ? AND attachmentId = ? AND isDeleted = 0`;
|
: `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`;
|
||||||
|
|
||||||
return sql.getRows(query, [this.noteId, attachmentId])
|
return sql.getRows(query, [this.noteId, attachmentId])
|
||||||
.map(row => new BAttachment(row))[0];
|
.map(row => new BAttachment(row))[0];
|
||||||
@ -1129,7 +1129,7 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
return sql.getRows(`
|
return sql.getRows(`
|
||||||
SELECT attachments.*
|
SELECT attachments.*
|
||||||
FROM attachments
|
FROM attachments
|
||||||
WHERE parentId = ?
|
WHERE ownerId = ?
|
||||||
AND role = ?
|
AND role = ?
|
||||||
AND isDeleted = 0
|
AND isDeleted = 0
|
||||||
ORDER BY position`, [this.noteId, role])
|
ORDER BY position`, [this.noteId, role])
|
||||||
@ -1590,7 +1590,7 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const revisionAttachment = noteAttachment.copy();
|
const revisionAttachment = noteAttachment.copy();
|
||||||
revisionAttachment.parentId = revision.revisionId;
|
revisionAttachment.ownerId = revision.revisionId;
|
||||||
revisionAttachment.setContent(noteAttachment.getContent(), {forceSave: true});
|
revisionAttachment.setContent(noteAttachment.getContent(), {forceSave: true});
|
||||||
|
|
||||||
// content is rewritten to point to the revision attachments
|
// content is rewritten to point to the revision attachments
|
||||||
@ -1618,7 +1618,7 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
attachment = this.becca.getAttachmentOrThrow(attachmentId);
|
attachment = this.becca.getAttachmentOrThrow(attachmentId);
|
||||||
} else {
|
} else {
|
||||||
attachment = new BAttachment({
|
attachment = new BAttachment({
|
||||||
parentId: this.noteId,
|
ownerId: this.noteId,
|
||||||
title,
|
title,
|
||||||
role,
|
role,
|
||||||
mime,
|
mime,
|
||||||
|
@ -100,7 +100,7 @@ class BRevision extends AbstractBeccaEntity {
|
|||||||
return sql.getRows(`
|
return sql.getRows(`
|
||||||
SELECT attachments.*
|
SELECT attachments.*
|
||||||
FROM attachments
|
FROM attachments
|
||||||
WHERE parentId = ?
|
WHERE ownerId = ?
|
||||||
AND isDeleted = 0`, [this.revisionId])
|
AND isDeleted = 0`, [this.revisionId])
|
||||||
.map(row => new BAttachment(row));
|
.map(row => new BAttachment(row));
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ const utils = require("../services/utils");
|
|||||||
|
|
||||||
function register(router) {
|
function register(router) {
|
||||||
const ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT = {
|
const ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT = {
|
||||||
'parentId': [v.notNull, v.isNoteId],
|
'ownerId': [v.notNull, v.isNoteId],
|
||||||
'role': [v.notNull, v.isString],
|
'role': [v.notNull, v.isString],
|
||||||
'mime': [v.notNull, v.isString],
|
'mime': [v.notNull, v.isString],
|
||||||
'title': [v.notNull, v.isString],
|
'title': [v.notNull, v.isString],
|
||||||
@ -20,7 +20,7 @@ function register(router) {
|
|||||||
eu.validateAndPatch(params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT);
|
eu.validateAndPatch(params, req.body, ALLOWED_PROPERTIES_FOR_CREATE_ATTACHMENT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const note = becca.getNoteOrThrow(params.parentId);
|
const note = becca.getNoteOrThrow(params.ownerId);
|
||||||
const attachment = note.saveAttachment(params);
|
const attachment = note.saveAttachment(params);
|
||||||
|
|
||||||
res.status(201).json(mappers.mapAttachmentToPojo(attachment));
|
res.status(201).json(mappers.mapAttachmentToPojo(attachment));
|
||||||
|
@ -50,7 +50,7 @@ function mapAttributeToPojo(attr) {
|
|||||||
function mapAttachmentToPojo(attachment) {
|
function mapAttachmentToPojo(attachment) {
|
||||||
return {
|
return {
|
||||||
attachmentId: attachment.attachmentId,
|
attachmentId: attachment.attachmentId,
|
||||||
parentId: attachment.parentId,
|
ownerId: attachment.ownerId,
|
||||||
role: attachment.role,
|
role: attachment.role,
|
||||||
mime: attachment.mime,
|
mime: attachment.mime,
|
||||||
title: attachment.title,
|
title: attachment.title,
|
||||||
|
@ -9,7 +9,7 @@ class FAttachment {
|
|||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
this.attachmentId = row.attachmentId;
|
this.attachmentId = row.attachmentId;
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
this.parentId = row.parentId;
|
this.ownerId = row.ownerId;
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
this.role = row.role;
|
this.role = row.role;
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
@ -31,7 +31,7 @@ class FAttachment {
|
|||||||
|
|
||||||
/** @returns {FNote} */
|
/** @returns {FNote} */
|
||||||
getNote() {
|
getNote() {
|
||||||
return this.froca.notes[this.parentId];
|
return this.froca.notes[this.ownerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,7 +280,7 @@ function processAttachment(loadResults, ec) {
|
|||||||
if (attachment) {
|
if (attachment) {
|
||||||
attachment.update(ec.entity);
|
attachment.update(ec.entity);
|
||||||
} else {
|
} else {
|
||||||
const note = froca.notes[ec.entity.parentId];
|
const note = froca.notes[ec.entity.ownerId];
|
||||||
|
|
||||||
if (note?.attachments) {
|
if (note?.attachments) {
|
||||||
note.attachments.push(new FAttachment(froca, ec.entity));
|
note.attachments.push(new FAttachment(froca, ec.entity));
|
||||||
|
@ -126,7 +126,7 @@ export default class AttachmentDetailWidget extends BasicWidget {
|
|||||||
|
|
||||||
if (!this.isFullDetail) {
|
if (!this.isFullDetail) {
|
||||||
this.$wrapper.find('.attachment-title').append(
|
this.$wrapper.find('.attachment-title').append(
|
||||||
await linkService.createLink(this.attachment.parentId, {
|
await linkService.createLink(this.attachment.ownerId, {
|
||||||
title: this.attachment.title,
|
title: this.attachment.title,
|
||||||
viewScope: {
|
viewScope: {
|
||||||
viewMode: 'attachments',
|
viewMode: 'attachments',
|
||||||
@ -174,7 +174,7 @@ export default class AttachmentDetailWidget extends BasicWidget {
|
|||||||
if (this.attachment.role === 'image') {
|
if (this.attachment.role === 'image') {
|
||||||
imageService.copyImageReferenceToClipboard(this.$wrapper.find('.attachment-content-wrapper'));
|
imageService.copyImageReferenceToClipboard(this.$wrapper.find('.attachment-content-wrapper'));
|
||||||
} else if (this.attachment.role === 'file') {
|
} else if (this.attachment.role === 'file') {
|
||||||
const $link = await linkService.createLink(this.attachment.parentId, {
|
const $link = await linkService.createLink(this.attachment.ownerId, {
|
||||||
referenceLink: true,
|
referenceLink: true,
|
||||||
viewScope: {
|
viewScope: {
|
||||||
viewMode: 'attachments',
|
viewMode: 'attachments',
|
||||||
|
@ -121,7 +121,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
toastService.showMessage(`Note '${newAttachment.title}' has been converted to attachment.`);
|
toastService.showMessage(`Note '${newAttachment.title}' has been converted to attachment.`);
|
||||||
await ws.waitForMaxKnownEntityChangeId();
|
await ws.waitForMaxKnownEntityChangeId();
|
||||||
await appContext.tabManager.getActiveContext().setNote(newAttachment.parentId, {
|
await appContext.tabManager.getActiveContext().setNote(newAttachment.ownerId, {
|
||||||
viewScope: {
|
viewScope: {
|
||||||
viewMode: 'attachments',
|
viewMode: 'attachments',
|
||||||
attachmentId: newAttachment.attachmentId
|
attachmentId: newAttachment.attachmentId
|
||||||
|
@ -60,7 +60,7 @@ export default class AbstractTextTypeWidget extends TypeWidget {
|
|||||||
const attachment = await froca.getAttachment(attachmentId);
|
const attachment = await froca.getAttachment(attachmentId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
noteId: attachment.parentId,
|
noteId: attachment.ownerId,
|
||||||
viewScope: {
|
viewScope: {
|
||||||
viewMode: 'attachments',
|
viewMode: 'attachments',
|
||||||
attachmentId: attachmentId
|
attachmentId: attachmentId
|
||||||
|
@ -112,7 +112,7 @@ function restoreRevision(req) {
|
|||||||
|
|
||||||
for (const revisionAttachment of revision.getAttachments()) {
|
for (const revisionAttachment of revision.getAttachments()) {
|
||||||
const noteAttachment = revisionAttachment.copy();
|
const noteAttachment = revisionAttachment.copy();
|
||||||
noteAttachment.parentId = note.noteId;
|
noteAttachment.ownerId = note.noteId;
|
||||||
noteAttachment.setContent(revisionAttachment.getContent(), { forceSave: true });
|
noteAttachment.setContent(revisionAttachment.getContent(), { forceSave: true });
|
||||||
|
|
||||||
// content is rewritten to point to the restored revision attachments
|
// content is rewritten to point to the restored revision attachments
|
||||||
|
@ -8,7 +8,7 @@ function getNoteSize(req) {
|
|||||||
SELECT blobs.blobId, LENGTH(content)
|
SELECT blobs.blobId, LENGTH(content)
|
||||||
FROM blobs
|
FROM blobs
|
||||||
LEFT JOIN notes ON notes.blobId = blobs.blobId AND notes.noteId = ? AND notes.isDeleted = 0
|
LEFT JOIN notes ON notes.blobId = blobs.blobId AND notes.noteId = ? AND notes.isDeleted = 0
|
||||||
LEFT JOIN attachments ON attachments.blobId = blobs.blobId AND attachments.parentId = ? AND attachments.isDeleted = 0
|
LEFT JOIN attachments ON attachments.blobId = blobs.blobId AND attachments.ownerId = ? AND attachments.isDeleted = 0
|
||||||
LEFT JOIN revisions ON revisions.blobId = blobs.blobId AND revisions.noteId = ?
|
LEFT JOIN revisions ON revisions.blobId = blobs.blobId AND revisions.noteId = ?
|
||||||
WHERE notes.noteId IS NOT NULL
|
WHERE notes.noteId IS NOT NULL
|
||||||
OR attachments.attachmentId IS NOT NULL
|
OR attachments.attachmentId IS NOT NULL
|
||||||
@ -32,7 +32,7 @@ function getSubtreeSize(req) {
|
|||||||
SELECT blobs.blobId, LENGTH(content)
|
SELECT blobs.blobId, LENGTH(content)
|
||||||
FROM param_list
|
FROM param_list
|
||||||
JOIN notes ON notes.noteId = param_list.paramId AND notes.isDeleted = 0
|
JOIN notes ON notes.noteId = param_list.paramId AND notes.isDeleted = 0
|
||||||
LEFT JOIN attachments ON attachments.parentId = param_list.paramId AND attachments.isDeleted = 0
|
LEFT JOIN attachments ON attachments.ownerId = param_list.paramId AND attachments.isDeleted = 0
|
||||||
LEFT JOIN revisions ON revisions.noteId = param_list.paramId
|
LEFT JOIN revisions ON revisions.noteId = param_list.paramId
|
||||||
JOIN blobs ON blobs.blobId = notes.blobId OR blobs.blobId = attachments.blobId OR blobs.blobId = revisions.blobId`);
|
JOIN blobs ON blobs.blobId = notes.blobId OR blobs.blobId = attachments.blobId OR blobs.blobId = revisions.blobId`);
|
||||||
|
|
||||||
|
@ -215,24 +215,24 @@ class ConsistencyChecks {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT attachmentId, attachments.parentId AS noteId
|
SELECT attachmentId, attachments.ownerId AS noteId
|
||||||
FROM attachments
|
FROM attachments
|
||||||
WHERE attachments.parentId NOT IN (
|
WHERE attachments.ownerId NOT IN (
|
||||||
SELECT noteId FROM notes
|
SELECT noteId FROM notes
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT revisionId FROM revisions
|
SELECT revisionId FROM revisions
|
||||||
)
|
)
|
||||||
AND attachments.isDeleted = 0`,
|
AND attachments.isDeleted = 0`,
|
||||||
({attachmentId, parentId}) => {
|
({attachmentId, ownerId}) => {
|
||||||
if (this.autoFix) {
|
if (this.autoFix) {
|
||||||
const attachment = becca.getAttachment(attachmentId);
|
const attachment = becca.getAttachment(attachmentId);
|
||||||
attachment.markAsDeleted();
|
attachment.markAsDeleted();
|
||||||
|
|
||||||
this.reloadNeeded = false;
|
this.reloadNeeded = false;
|
||||||
|
|
||||||
logFix(`Attachment '${attachmentId}' has been deleted since it references missing note/revision '${parentId}'`);
|
logFix(`Attachment '${attachmentId}' has been deleted since it references missing note/revision '${ownerId}'`);
|
||||||
} else {
|
} else {
|
||||||
logError(`Attachment '${attachmentId}' references missing note/revision '${parentId}'`);
|
logError(`Attachment '${attachmentId}' references missing note/revision '${ownerId}'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -345,9 +345,9 @@ class ConsistencyChecks {
|
|||||||
|
|
||||||
this.findAndFixIssues(`
|
this.findAndFixIssues(`
|
||||||
SELECT attachmentId,
|
SELECT attachmentId,
|
||||||
attachments.parentId AS noteId
|
attachments.ownerId AS noteId
|
||||||
FROM attachments
|
FROM attachments
|
||||||
JOIN notes ON notes.noteId = attachments.parentId
|
JOIN notes ON notes.noteId = attachments.ownerId
|
||||||
WHERE notes.isDeleted = 1
|
WHERE notes.isDeleted = 1
|
||||||
AND attachments.isDeleted = 0`,
|
AND attachments.isDeleted = 0`,
|
||||||
({attachmentId, noteId}) => {
|
({attachmentId, noteId}) => {
|
||||||
|
@ -452,7 +452,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
|
|||||||
if (attachmentMeta) {
|
if (attachmentMeta) {
|
||||||
const attachment = new BAttachment({
|
const attachment = new BAttachment({
|
||||||
attachmentId: getNewAttachmentId(attachmentMeta.attachmentId),
|
attachmentId: getNewAttachmentId(attachmentMeta.attachmentId),
|
||||||
parentId: noteId,
|
ownerId: noteId,
|
||||||
title: attachmentMeta.title,
|
title: attachmentMeta.title,
|
||||||
role: attachmentMeta.role,
|
role: attachmentMeta.role,
|
||||||
mime: attachmentMeta.mime,
|
mime: attachmentMeta.mime,
|
||||||
|
@ -378,21 +378,21 @@ function checkImageAttachments(note, content) {
|
|||||||
localAttachment.save();
|
localAttachment.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`Found equivalent attachment '${localAttachment.attachmentId}' of note '${note.noteId}' for the linked foreign attachment '${unknownAttachment.attachmentId}' of note '${unknownAttachment.parentId}'`);
|
log.info(`Found equivalent attachment '${localAttachment.attachmentId}' of note '${note.noteId}' for the linked foreign attachment '${unknownAttachment.attachmentId}' of note '${unknownAttachment.ownerId}'`);
|
||||||
} else {
|
} else {
|
||||||
localAttachment = unknownAttachment.copy();
|
localAttachment = unknownAttachment.copy();
|
||||||
localAttachment.parentId = note.noteId;
|
localAttachment.ownerId = note.noteId;
|
||||||
localAttachment.setContent(unknownAttachment.getContent(), {forceSave: true});
|
localAttachment.setContent(unknownAttachment.getContent(), {forceSave: true});
|
||||||
|
|
||||||
ws.sendMessageToAllClients({ type: 'toast', message: `Attachment '${localAttachment.title}' has been copied to note '${note.title}'.`});
|
ws.sendMessageToAllClients({ type: 'toast', message: `Attachment '${localAttachment.title}' has been copied to note '${note.title}'.`});
|
||||||
log.info(`Copied attachment '${unknownAttachment.attachmentId}' of note '${unknownAttachment.parentId}' to new '${localAttachment.attachmentId}' of note '${note.noteId}'`);
|
log.info(`Copied attachment '${unknownAttachment.attachmentId}' of note '${unknownAttachment.ownerId}' to new '${localAttachment.attachmentId}' of note '${note.noteId}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace image links
|
// replace image links
|
||||||
content = content.replace(`api/attachments/${unknownAttachment.attachmentId}/image`, `api/attachments/${localAttachment.attachmentId}/image`);
|
content = content.replace(`api/attachments/${unknownAttachment.attachmentId}/image`, `api/attachments/${localAttachment.attachmentId}/image`);
|
||||||
// replace reference links
|
// replace reference links
|
||||||
content = content.replace(new RegExp(`href="[^"]+attachmentId=${unknownAttachment.attachmentId}[^"]*"`, "g"),
|
content = content.replace(new RegExp(`href="[^"]+attachmentId=${unknownAttachment.attachmentId}[^"]*"`, "g"),
|
||||||
`href="#root/${localAttachment.parentId}?viewMode=attachments&attachmentId=${localAttachment.attachmentId}"`);
|
`href="#root/${localAttachment.ownerId}?viewMode=attachments&attachmentId=${localAttachment.attachmentId}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -48,7 +48,7 @@ function checkAttachmentAccess(attachmentId, req, res) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const note = checkNoteAccess(attachment.parentId, req, res);
|
const note = checkNoteAccess(attachment.ownerId, req, res);
|
||||||
|
|
||||||
// truthy note means the user has access, and we can return the attachment
|
// truthy note means the user has access, and we can return the attachment
|
||||||
return note ? attachment : false;
|
return note ? attachment : false;
|
||||||
|
@ -5,13 +5,13 @@ const utils = require('../../../services/utils');
|
|||||||
const AbstractShacaEntity = require('./abstract_shaca_entity');
|
const AbstractShacaEntity = require('./abstract_shaca_entity');
|
||||||
|
|
||||||
class SAttachment extends AbstractShacaEntity {
|
class SAttachment extends AbstractShacaEntity {
|
||||||
constructor([attachmentId, parentId, role, mime, title, blobId, utcDateModified]) {
|
constructor([attachmentId, ownerId, role, mime, title, blobId, utcDateModified]) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.attachmentId = attachmentId;
|
this.attachmentId = attachmentId;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.parentId = parentId;
|
this.ownerId = ownerId;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
this.title = title;
|
this.title = title;
|
||||||
/** @param {string} */
|
/** @param {string} */
|
||||||
@ -24,12 +24,12 @@ class SAttachment extends AbstractShacaEntity {
|
|||||||
this.utcDateModified = utcDateModified; // used for caching of images
|
this.utcDateModified = utcDateModified; // used for caching of images
|
||||||
|
|
||||||
this.shaca.attachments[this.attachmentId] = this;
|
this.shaca.attachments[this.attachmentId] = this;
|
||||||
this.shaca.notes[this.parentId].attachments.push(this);
|
this.shaca.notes[this.ownerId].attachments.push(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {SNote} */
|
/** @returns {SNote} */
|
||||||
get note() {
|
get note() {
|
||||||
return this.shaca.notes[this.parentId];
|
return this.shaca.notes[this.ownerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
getContent(silentNotFoundError = false) {
|
getContent(silentNotFoundError = false) {
|
||||||
|
@ -67,10 +67,10 @@ function load() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rawAttachmentRows = sql.getRawRows(`
|
const rawAttachmentRows = sql.getRawRows(`
|
||||||
SELECT attachmentId, parentId, role, mime, title, blobId, utcDateModified
|
SELECT attachmentId, ownerId, role, mime, title, blobId, utcDateModified
|
||||||
FROM attachments
|
FROM attachments
|
||||||
WHERE isDeleted = 0
|
WHERE isDeleted = 0
|
||||||
AND parentId IN (${noteIdStr})`);
|
AND ownerId IN (${noteIdStr})`);
|
||||||
|
|
||||||
rawAttachmentRows.sort((a, b) => a.position < b.position ? -1 : 1);
|
rawAttachmentRows.sort((a, b) => a.position < b.position ? -1 : 1);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ Content-Type: application/json
|
|||||||
Authorization: {{authToken}}
|
Authorization: {{authToken}}
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "{{createdNoteId}}",
|
"ownerId": "{{createdNoteId}}",
|
||||||
"role": "file",
|
"role": "file",
|
||||||
"mime": "plain/text",
|
"mime": "plain/text",
|
||||||
"title": "my attachment",
|
"title": "my attachment",
|
||||||
|
@ -18,7 +18,7 @@ Authorization: {{authToken}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "{{createdNoteId}}",
|
"ownerId": "{{createdNoteId}}",
|
||||||
"role": "file",
|
"role": "file",
|
||||||
"mime": "text/plain",
|
"mime": "text/plain",
|
||||||
"title": "my attachment",
|
"title": "my attachment",
|
||||||
|
@ -18,7 +18,7 @@ Authorization: {{authToken}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "{{createdNoteId}}",
|
"ownerId": "{{createdNoteId}}",
|
||||||
"role": "file",
|
"role": "file",
|
||||||
"mime": "text/plain",
|
"mime": "text/plain",
|
||||||
"title": "my attachment",
|
"title": "my attachment",
|
||||||
@ -55,7 +55,7 @@ Authorization: {{authToken}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "root"
|
"ownerId": "root"
|
||||||
}
|
}
|
||||||
|
|
||||||
> {%
|
> {%
|
||||||
|
@ -18,7 +18,7 @@ Authorization: {{authToken}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "{{createdNoteId}}",
|
"ownerId": "{{createdNoteId}}",
|
||||||
"role": "file",
|
"role": "file",
|
||||||
"mime": "text/plain",
|
"mime": "text/plain",
|
||||||
"title": "my attachment",
|
"title": "my attachment",
|
||||||
|
@ -18,7 +18,7 @@ Authorization: {{authToken}}
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"parentId": "{{createdNoteId}}",
|
"ownerId": "{{createdNoteId}}",
|
||||||
"role": "file",
|
"role": "file",
|
||||||
"mime": "text/plain",
|
"mime": "text/plain",
|
||||||
"title": "my attachment",
|
"title": "my attachment",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user