ancillary => attachment

This commit is contained in:
zadam 2023-03-16 11:03:28 +01:00
parent e16bedfab4
commit dc97400dbf
20 changed files with 161 additions and 161 deletions

View File

@ -1,6 +1,6 @@
CREATE TABLE IF NOT EXISTS "note_ancillaries"
CREATE TABLE IF NOT EXISTS "note_attachments"
(
noteAncillaryId TEXT not null primary key,
noteAttachmentId TEXT not null primary key,
noteId TEXT not null,
name TEXT not null,
mime TEXT not null,
@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS "note_ancillaries"
isDeleted INT not null,
`deleteId` TEXT DEFAULT NULL);
CREATE INDEX IDX_note_ancillaries_name
on note_ancillaries (name);
CREATE UNIQUE INDEX IDX_note_ancillaries_noteId_name
on note_ancillaries (noteId, name);
CREATE INDEX IDX_note_attachments_name
on note_attachments (name);
CREATE UNIQUE INDEX IDX_note_attachments_noteId_name
on note_attachments (noteId, name);

View File

@ -112,9 +112,9 @@ CREATE TABLE IF NOT EXISTS "recent_notes"
notePath TEXT not null,
utcDateCreated TEXT not null
);
CREATE TABLE IF NOT EXISTS "note_ancillaries"
CREATE TABLE IF NOT EXISTS "note_attachments"
(
noteAncillaryId TEXT not null primary key,
noteAttachmentId TEXT not null primary key,
noteId TEXT not null,
name TEXT not null,
mime TEXT not null,
@ -123,7 +123,7 @@ CREATE TABLE IF NOT EXISTS "note_ancillaries"
isDeleted INT not null,
`deleteId` TEXT DEFAULT NULL);
CREATE INDEX IDX_note_ancillaries_name
on note_ancillaries (name);
CREATE UNIQUE INDEX IDX_note_ancillaries_noteId_name
on note_ancillaries (noteId, name);
CREATE INDEX IDX_note_attachments_name
on note_attachments (name);
CREATE UNIQUE INDEX IDX_note_attachments_noteId_name
on note_attachments (noteId, name);

View File

@ -121,12 +121,12 @@ class Becca {
return row ? new BNoteRevision(row) : null;
}
/** @returns {BNoteAncillary|null} */
getNoteAncillary(noteAncillaryId) {
const row = sql.getRow("SELECT * FROM note_ancillaries WHERE noteAncillaryId = ?", [noteAncillaryId]);
/** @returns {BNoteAttachment|null} */
getNoteAttachment(noteAttachmentId) {
const row = sql.getRow("SELECT * FROM note_attachments WHERE noteAttachmentId = ?", [noteAttachmentId]);
const BNoteAncillary = require("./entities/bnote_attachment.js"); // avoiding circular dependency problems
return row ? new BNoteAncillary(row) : null;
const BNoteAttachment = require("./entities/bnote_attachment.js"); // avoiding circular dependency problems
return row ? new BNoteAttachment(row) : null;
}
/** @returns {BOption|null} */
@ -151,8 +151,8 @@ class Becca {
if (entityName === 'note_revisions') {
return this.getNoteRevision(entityId);
} else if (entityName === 'note_ancillaries') {
return this.getNoteAncillary(entityId);
} else if (entityName === 'note_attachments') {
return this.getNoteAttachment(entityId);
}
const camelCaseEntityName = entityName.toLowerCase().replace(/(_[a-z])/g,

View File

@ -198,8 +198,8 @@ class BBranch extends AbstractBeccaEntity {
relation.markAsDeleted(deleteId);
}
for (const noteAncillary of note.getNoteAncillaries()) {
noteAncillary.markAsDeleted(deleteId);
for (const noteAttachment of note.getNoteAttachments()) {
noteAttachment.markAsDeleted(deleteId);
}
note.markAsDeleted(deleteId);

View File

@ -8,7 +8,7 @@ const dateUtils = require('../../services/date_utils');
const entityChangesService = require('../../services/entity_changes');
const AbstractBeccaEntity = require("./abstract_becca_entity");
const BNoteRevision = require("./bnote_revision");
const BNoteAncillary = require("./bnote_attachment.js");
const BNoteAttachment = require("./bnote_attachment.js");
const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
@ -1161,16 +1161,16 @@ class BNote extends AbstractBeccaEntity {
.map(row => new BNoteRevision(row));
}
/** @returns {BNoteAncillary[]} */
getNoteAncillaries() {
return sql.getRows("SELECT * FROM note_ancillaries WHERE noteId = ? AND isDeleted = 0", [this.noteId])
.map(row => new BNoteAncillary(row));
/** @returns {BNoteAttachment[]} */
getNoteAttachments() {
return sql.getRows("SELECT * FROM note_attachments WHERE noteId = ? AND isDeleted = 0", [this.noteId])
.map(row => new BNoteAttachment(row));
}
/** @returns {BNoteAncillary|undefined} */
getNoteAncillaryByName(name) {
return sql.getRows("SELECT * FROM note_ancillaries WHERE noteId = ? AND name = ? AND isDeleted = 0", [this.noteId, name])
.map(row => new BNoteAncillary(row))
/** @returns {BNoteAttachment|undefined} */
getNoteAttachmentByName(name) {
return sql.getRows("SELECT * FROM note_attachments WHERE noteId = ? AND name = ? AND isDeleted = 0", [this.noteId, name])
.map(row => new BNoteAttachment(row))
[0];
}
@ -1502,21 +1502,21 @@ class BNote extends AbstractBeccaEntity {
}
/**
* @returns {BNoteAncillary}
* @returns {BNoteAttachment}
*/
saveNoteAncillary(name, mime, content) {
let noteAncillary = this.getNoteAncillaryByName(name);
saveNoteAttachment(name, mime, content) {
let noteAttachment = this.getNoteAttachmentByName(name);
noteAncillary = new BNoteAncillary({
noteAttachment = new BNoteAttachment({
noteId: this.noteId,
name,
mime,
isProtected: this.isProtected
});
noteAncillary.setContent(content);
noteAttachment.setContent(content);
return noteAncillary;
return noteAttachment;
}
beforeSaving() {

View File

@ -9,29 +9,29 @@ const entityChangesService = require('../../services/entity_changes');
const AbstractBeccaEntity = require("./abstract_becca_entity");
/**
* NoteAncillary represent data related/attached to the note. Conceptually similar to attributes, but intended for
* NoteAttachment represent data related/attached to the note. Conceptually similar to attributes, but intended for
* larger amounts of data and generally not accessible to the user.
*
* @extends AbstractBeccaEntity
*/
class BNoteAncillary extends AbstractBeccaEntity {
static get entityName() { return "note_ancillaries"; }
static get primaryKeyName() { return "noteAncillaryId"; }
static get hashedProperties() { return ["noteAncillaryId", "noteId", "name", "content", "utcDateModified"]; }
class BNoteAttachment extends AbstractBeccaEntity {
static get entityName() { return "note_attachments"; }
static get primaryKeyName() { return "noteAttachmentId"; }
static get hashedProperties() { return ["noteAttachmentId", "noteId", "name", "content", "utcDateModified"]; }
constructor(row) {
super();
if (!row.noteId) {
throw new Error("'noteId' must be given to initialize a NoteAncillary entity");
throw new Error("'noteId' must be given to initialize a NoteAttachment entity");
}
if (!row.name) {
throw new Error("'name' must be given to initialize a NoteAncillary entity");
throw new Error("'name' must be given to initialize a NoteAttachment entity");
}
/** @type {string} needs to be set at the initialization time since it's used in the .setContent() */
this.noteAncillaryId = row.noteAncillaryId || `${this.noteId}_${this.name}`;
this.noteAttachmentId = row.noteAttachmentId || `${this.noteId}_${this.name}`;
/** @type {string} */
this.noteId = row.noteId;
/** @type {string} */
@ -55,14 +55,14 @@ class BNoteAncillary extends AbstractBeccaEntity {
/** @returns {*} */
getContent(silentNotFoundError = false) {
const res = sql.getRow(`SELECT content FROM note_ancillary_contents WHERE noteAncillaryId = ?`, [this.noteAncillaryId]);
const res = sql.getRow(`SELECT content FROM note_attachment_contents WHERE noteAttachmentId = ?`, [this.noteAttachmentId]);
if (!res) {
if (silentNotFoundError) {
return undefined;
}
else {
throw new Error(`Cannot find note ancillary content for noteAncillaryId=${this.noteAncillaryId}`);
throw new Error(`Cannot find note attachment content for noteAttachmentId=${this.noteAttachmentId}`);
}
}
@ -89,10 +89,10 @@ class BNoteAncillary extends AbstractBeccaEntity {
setContent(content) {
sql.transactional(() => {
this.save(); // also explicitly save note_ancillary to update contentCheckSum
this.save(); // also explicitly save note_attachment to update contentCheckSum
const pojo = {
noteAncillaryId: this.noteAncillaryId,
noteAttachmentId: this.noteAttachmentId,
content: content,
utcDateModified: dateUtils.utcNowDateTime()
};
@ -101,15 +101,15 @@ class BNoteAncillary extends AbstractBeccaEntity {
if (protectedSessionService.isProtectedSessionAvailable()) {
pojo.content = protectedSessionService.encrypt(pojo.content);
} else {
throw new Error(`Cannot update content of noteAncillaryId=${this.noteAncillaryId} since we're out of protected session.`);
throw new Error(`Cannot update content of noteAttachmentId=${this.noteAttachmentId} since we're out of protected session.`);
}
}
sql.upsert("note_ancillary_contents", "noteAncillaryId", pojo);
sql.upsert("note_attachment_contents", "noteAttachmentId", pojo);
entityChangesService.addEntityChange({
entityName: 'note_ancillary_contents',
entityId: this.noteAncillaryId,
entityName: 'note_attachment_contents',
entityId: this.noteAttachmentId,
hash: this.contentCheckSum, // FIXME
isErased: false,
utcDateChanged: pojo.utcDateModified,
@ -119,7 +119,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
}
calculateCheckSum(content) {
return utils.hash(`${this.noteAncillaryId}|${content.toString()}`);
return utils.hash(`${this.noteAttachmentId}|${content.toString()}`);
}
beforeSaving() {
@ -127,7 +127,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
throw new Error(`Name must be alphanumerical, "${this.name}" given.`);
}
this.noteAncillaryId = `${this.noteId}_${this.name}`;
this.noteAttachmentId = `${this.noteId}_${this.name}`;
super.beforeSaving();
@ -136,7 +136,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
getPojo() {
return {
noteAncillaryId: this.noteAncillaryId,
noteAttachmentId: this.noteAttachmentId,
noteId: this.noteId,
name: this.name,
mime: this.mime,
@ -155,4 +155,4 @@ class BNoteAncillary extends AbstractBeccaEntity {
}
}
module.exports = BNoteAncillary;
module.exports = BNoteAttachment;

View File

@ -1,6 +1,6 @@
const BNote = require('./entities/bnote');
const BNoteRevision = require('./entities/bnote_revision');
const BNoteAncillary = require("./entities/bnote_attachment.js");
const BNoteAttachment = require("./entities/bnote_attachment.js");
const BBranch = require('./entities/bbranch');
const BAttribute = require('./entities/battribute');
const BRecentNote = require('./entities/brecent_note');
@ -12,7 +12,7 @@ const ENTITY_NAME_TO_ENTITY = {
"branches": BBranch,
"notes": BNote,
"note_revisions": BNoteRevision,
"note_ancillaries": BNoteAncillary,
"note_attachments": BNoteAttachment,
"recent_notes": BRecentNote,
"etapi_tokens": BEtapiToken,
"options": BOption

View File

@ -34,7 +34,7 @@ async function processEntityChanges(entityChanges) {
loadResults.addOption(ec.entity.name);
}
else if (['etapi_tokens', 'note_ancillaries'].includes(ec.entityName)) {
else if (['etapi_tokens', 'note_attachments'].includes(ec.entityName)) {
// NOOP
}
else {

View File

@ -28,7 +28,7 @@ const TPL = `
<a data-trigger-command="renderActiveNote" class="dropdown-item render-note-button"><kbd data-command="renderActiveNote"></kbd> Re-render note</a>
<a data-trigger-command="findInText" class="dropdown-item find-in-text-button">Search in note <kbd data-command="findInText"></a>
<a data-trigger-command="showNoteSource" class="dropdown-item show-source-button"><kbd data-command="showNoteSource"></kbd> Note source</a>
<a data-trigger-command="showNoteAncillaries" class="dropdown-item"><kbd data-command="showNoteAncillaries"></kbd> Note ancillaries</a>
<a data-trigger-command="showNoteAttachments" class="dropdown-item"><kbd data-command="showNoteAttachments"></kbd> Note attachments</a>
<a data-trigger-command="openNoteExternally" class="dropdown-item open-note-externally-button"><kbd data-command="openNoteExternally"></kbd> Open note externally</a>
<a class="dropdown-item import-files-button">Import files</a>
<a class="dropdown-item export-note-button">Export note</a>

View File

@ -27,7 +27,7 @@ import NoteMapTypeWidget from "./type_widgets/note_map.js";
import WebViewTypeWidget from "./type_widgets/web_view.js";
import DocTypeWidget from "./type_widgets/doc.js";
import ContentWidgetTypeWidget from "./type_widgets/content_widget.js";
import AncillariesTypeWidget from "./type_widgets/attachments.js";
import AttachmentsTypeWidget from "./type_widgets/attachments.js";
const TPL = `
<div class="note-detail">
@ -63,7 +63,7 @@ const typeWidgetClasses = {
'webView': WebViewTypeWidget,
'doc': DocTypeWidget,
'contentWidget': ContentWidgetTypeWidget,
'ancillaries': AncillariesTypeWidget
'attachments': AttachmentsTypeWidget
};
export default class NoteDetailWidget extends NoteContextAwareWidget {
@ -191,8 +191,8 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
if (type === 'text' && this.noteContext.viewScope.viewMode === 'source') {
type = 'readOnlyCode';
} else if (this.noteContext.viewScope.viewMode === 'ancillaries') {
type = 'ancillaries';
} else if (this.noteContext.viewScope.viewMode === 'attachments') {
type = 'attachments';
} else if (type === 'text' && await this.noteContext.isReadOnly()) {
type = 'readOnlyText';
} else if ((type === 'code' || type === 'mermaid') && await this.noteContext.isReadOnly()) {

View File

@ -2,13 +2,13 @@ import TypeWidget from "./type_widget.js";
import server from "../../services/server.js";
const TPL = `
<div class="note-ancillaries note-detail-printable">
<div class="note-attachments note-detail-printable">
<style>
.note-ancillaries {
.note-attachments {
padding: 15px;
}
.ancillary-content {
.attachment-content {
max-height: 400px;
background: var(--accented-background-color);
padding: 10px;
@ -16,26 +16,26 @@ const TPL = `
margin-bottom: 10px;
}
.ancillary-details th {
.attachment-details th {
padding-left: 10px;
padding-right: 10px;
}
</style>
<div class="alert alert-info" style="margin: 10px 0 10px 0; padding: 20px;">
Note ancillaries are pieces of data attached to a given note, providing ancillary support.
Note attachments are pieces of data attached to a given note, providing attachment support.
This view is useful for diagnostics.
</div>
<div class="note-ancillary-list"></div>
<div class="note-attachment-list"></div>
</div>`;
export default class AncillariesTypeWidget extends TypeWidget {
static getType() { return "ancillaries"; }
export default class AttachmentsTypeWidget extends TypeWidget {
static getType() { return "attachments"; }
doRender() {
this.$widget = $(TPL);
this.$list = this.$widget.find('.note-ancillary-list');
this.$list = this.$widget.find('.note-attachment-list');
super.doRender();
}
@ -43,35 +43,35 @@ export default class AncillariesTypeWidget extends TypeWidget {
async doRefresh(note) {
this.$list.empty();
const ancillaries = await server.get(`notes/${this.noteId}/ancillaries?includeContent=true`);
const attachments = await server.get(`notes/${this.noteId}/attachments?includeContent=true`);
if (ancillaries.length === 0) {
this.$list.html("<strong>This note has no ancillaries.</strong>");
if (attachments.length === 0) {
this.$list.html("<strong>This note has no attachments.</strong>");
return;
}
for (const ancillary of ancillaries) {
for (const attachment of attachments) {
this.$list.append(
$('<div class="note-ancillary-wrapper">')
$('<div class="note-attachment-wrapper">')
.append(
$('<h4>').append($('<span class="ancillary-name">').text(ancillary.name))
$('<h4>').append($('<span class="attachment-name">').text(attachment.name))
)
.append(
$('<table class="ancillary-details">')
$('<table class="attachment-details">')
.append(
$('<tr>')
.append($('<th>').text('Length:'))
.append($('<td>').text(ancillary.contentLength))
.append($('<td>').text(attachment.contentLength))
.append($('<th>').text('MIME:'))
.append($('<td>').text(ancillary.mime))
.append($('<td>').text(attachment.mime))
.append($('<th>').text('Date modified:'))
.append($('<td>').text(ancillary.utcDateModified))
.append($('<td>').text(attachment.utcDateModified))
)
)
.append(
$('<pre class="ancillary-content">')
.text(ancillary.content)
$('<pre class="attachment-content">')
.text(attachment.content)
)
);
}

View File

@ -54,10 +54,10 @@ function createNote(req) {
}
function updateNoteData(req) {
const {content, ancillaries} = req.body;
const {content, attachments} = req.body;
const {noteId} = req.params;
return noteService.updateNoteData(noteId, content, ancillaries);
return noteService.updateNoteData(noteId, content, attachments);
}
function deleteNote(req) {
@ -127,7 +127,7 @@ function setNoteTypeMime(req) {
note.save();
}
function getNoteAncillaries(req) {
function getNoteAttachments(req) {
const includeContent = req.query.includeContent === 'true';
const {noteId} = req.params;
@ -137,19 +137,19 @@ function getNoteAncillaries(req) {
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
}
const noteAncillaries = note.getNoteAncillaries();
const noteAttachments = note.getNoteAttachments();
return noteAncillaries.map(ancillary => {
const pojo = ancillary.getPojo();
return noteAttachments.map(attachment => {
const pojo = attachment.getPojo();
if (includeContent && utils.isStringNote(null, ancillary.mime)) {
pojo.content = ancillary.getContent()?.toString();
if (includeContent && utils.isStringNote(null, attachment.mime)) {
pojo.content = attachment.getContent()?.toString();
pojo.contentLength = pojo.content.length;
const MAX_ANCILLARY_LENGTH = 1_000_000;
const MAX_ATTACHMENT_LENGTH = 1_000_000;
if (pojo.content.length > MAX_ANCILLARY_LENGTH) {
pojo.content = pojo.content.substring(0, MAX_ANCILLARY_LENGTH);
if (pojo.content.length > MAX_ATTACHMENT_LENGTH) {
pojo.content = pojo.content.substring(0, MAX_ATTACHMENT_LENGTH);
}
}
@ -157,7 +157,7 @@ function getNoteAncillaries(req) {
});
}
function saveNoteAncillary(req) {
function saveNoteAttachment(req) {
const {noteId, name} = req.params;
const {mime, content} = req.body;
@ -167,7 +167,7 @@ function saveNoteAncillary(req) {
throw new NotFoundError(`Note '${noteId}' doesn't exist.`);
}
note.saveNoteAncillary(name, mime, content);
note.saveNoteAttachment(name, mime, content);
}
function getRelationMap(req) {
@ -384,6 +384,6 @@ module.exports = {
getDeleteNotesPreview,
uploadModifiedFile,
forceSaveNoteRevision,
getNoteAncillaries,
saveNoteAncillary
getNoteAttachments,
saveNoteAttachment
};

View File

@ -113,9 +113,9 @@ function forceNoteSync(req) {
entityChangesService.moveEntityChangeToTop('note_revisions', noteRevisionId);
}
for (const noteAncillaryId of sql.getColumn("SELECT noteAncillaryId FROM note_ancillaries WHERE noteId = ?", [noteId])) {
sql.execute(`UPDATE note_ancillaries SET utcDateModified = ? WHERE noteAncillaryId = ?`, [now, noteAncillaryId]);
entityChangesService.moveEntityChangeToTop('note_ancillaries', noteAncillaryId);
for (const noteAttachmentId of sql.getColumn("SELECT noteAttachmentId FROM note_attachments WHERE noteId = ?", [noteId])) {
sql.execute(`UPDATE note_attachments SET utcDateModified = ? WHERE noteAttachmentId = ?`, [now, noteAttachmentId]);
entityChangesService.moveEntityChangeToTop('note_attachments', noteAttachmentId);
}
log.info(`Forcing note sync for ${noteId}`);

View File

@ -126,8 +126,8 @@ function register(app) {
apiRoute(PUT, '/api/notes/:noteId/sort-children', notesApiRoute.sortChildNotes);
apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectNote);
apiRoute(PUT, '/api/notes/:noteId/type', notesApiRoute.setNoteTypeMime);
apiRoute(GET, '/api/notes/:noteId/ancillaries', notesApiRoute.getNoteAncillaries);
apiRoute(PUT, '/api/notes/:noteId/ancillaries/:name', notesApiRoute.saveNoteAncillary);
apiRoute(GET, '/api/notes/:noteId/attachments', notesApiRoute.getNoteAttachments);
apiRoute(PUT, '/api/notes/:noteId/attachments/:name', notesApiRoute.saveNoteAttachment);
apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions);
apiRoute(DELETE, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.eraseAllNoteRevisions);
apiRoute(GET, '/api/notes/:noteId/revisions/:noteRevisionId', noteRevisionsApiRoute.getNoteRevision);

View File

@ -215,21 +215,21 @@ class ConsistencyChecks {
});
this.findAndFixIssues(`
SELECT noteAncillaryId, note_ancillaries.noteId AS noteId
FROM note_ancillaries
SELECT noteAttachmentId, note_attachments.noteId AS noteId
FROM note_attachments
LEFT JOIN notes USING (noteId)
WHERE notes.noteId IS NULL
AND note_ancillaries.isDeleted = 0`,
({noteAncillaryId, noteId}) => {
AND note_attachments.isDeleted = 0`,
({noteAttachmentId, noteId}) => {
if (this.autoFix) {
const noteAncillary = becca.getNoteAncillary(noteAncillaryId);
noteAncillary.markAsDeleted();
const noteAttachment = becca.getNoteAttachment(noteAttachmentId);
noteAttachment.markAsDeleted();
this.reloadNeeded = false;
logFix(`Note ancillary '${noteAncillaryId}' has been deleted since it references missing note '${noteId}'`);
logFix(`Note attachment '${noteAttachmentId}' has been deleted since it references missing note '${noteId}'`);
} else {
logError(`Note ancillary '${noteAncillaryId}' references missing note '${noteId}'`);
logError(`Note attachment '${noteAttachmentId}' references missing note '${noteId}'`);
}
});
}
@ -341,22 +341,22 @@ class ConsistencyChecks {
});
this.findAndFixIssues(`
SELECT noteAncillaryId,
note_ancillaries.noteId AS noteId
FROM note_ancillaries
SELECT noteAttachmentId,
note_attachments.noteId AS noteId
FROM note_attachments
JOIN notes USING (noteId)
WHERE notes.isDeleted = 1
AND note_ancillaries.isDeleted = 0`,
({noteAncillaryId, noteId}) => {
AND note_attachments.isDeleted = 0`,
({noteAttachmentId, noteId}) => {
if (this.autoFix) {
const noteAncillary = becca.getNoteAncillary(noteAncillaryId);
noteAncillary.markAsDeleted();
const noteAttachment = becca.getNoteAttachment(noteAttachmentId);
noteAttachment.markAsDeleted();
this.reloadNeeded = false;
logFix(`Note ancillary '${noteAncillaryId}' has been deleted since associated note '${noteId}' is deleted.`);
logFix(`Note attachment '${noteAttachmentId}' has been deleted since associated note '${noteId}' is deleted.`);
} else {
logError(`Note ancillary '${noteAncillaryId}' is not deleted even though associated note '${noteId}' is deleted.`)
logError(`Note attachment '${noteAttachmentId}' is not deleted even though associated note '${noteId}' is deleted.`)
}
});
}
@ -657,7 +657,7 @@ class ConsistencyChecks {
findEntityChangeIssues() {
this.runEntityChangeChecks("notes", "noteId");
this.runEntityChangeChecks("note_revisions", "noteRevisionId");
this.runEntityChangeChecks("note_ancillaries", "noteAncillaryId");
this.runEntityChangeChecks("note_attachments", "noteAttachmentId");
this.runEntityChangeChecks("blobs", "blobId");
this.runEntityChangeChecks("branches", "branchId");
this.runEntityChangeChecks("attributes", "attributeId");
@ -754,7 +754,7 @@ class ConsistencyChecks {
return `${tableName}: ${count}`;
}
const tables = [ "notes", "note_revisions", "note_ancillaries", "branches", "attributes", "etapi_tokens" ];
const tables = [ "notes", "note_revisions", "note_attachments", "branches", "attributes", "etapi_tokens" ];
log.info(`Table counts: ${tables.map(tableName => getTableRowCount(tableName)).join(", ")}`);
}

View File

@ -149,7 +149,7 @@ function fillAllEntityChanges() {
fillEntityChanges("notes", "noteId");
fillEntityChanges("branches", "branchId");
fillEntityChanges("note_revisions", "noteRevisionId");
fillEntityChanges("note_ancillaries", "noteAncillaryId");
fillEntityChanges("note_attachments", "noteAttachmentId");
fillEntityChanges("blobs", "blobId");
fillEntityChanges("attributes", "attributeId");
fillEntityChanges("etapi_tokens", "etapiTokenId");

View File

@ -170,19 +170,19 @@ async function exportToZip(taskContext, branch, format, res, setHeaders = true)
meta.dataFileName = getDataFileName(note.type, note.mime, baseFileName, existingFileNames);
}
const ancillaries = note.getNoteAncillaries();
const attachments = note.getNoteAttachments();
if (ancillaries.length > 0) {
meta.ancillaries = ancillaries
.filter(ancillary => ["canvasSvg", "mermaidSvg"].includes(ancillary.name))
.map(ancillary => ({
if (attachments.length > 0) {
meta.attachments = attachments
.filter(attachment => ["canvasSvg", "mermaidSvg"].includes(attachment.name))
.map(attachment => ({
name: ancillary.name,
mime: ancillary.mime,
name: attachment.name,
mime: attachment.mime,
dataFileName: getDataFileName(
null,
ancillary.mime,
baseFileName + "_" + ancillary.name,
attachment.mime,
baseFileName + "_" + attachment.name,
existingFileNames
)
}));
@ -337,12 +337,12 @@ ${markdownContent}`;
taskContext.increaseProgressCount();
for (const ancillaryMeta of noteMeta.ancillaries || []) {
const noteAncillary = note.getNoteAncillaryByName(ancillaryMeta.name);
const content = noteAncillary.getContent();
for (const attachmentMeta of noteMeta.attachments || []) {
const noteAttachment = note.getNoteAttachmentByName(attachmentMeta.name);
const content = noteAttachment.getContent();
archive.append(content, {
name: filePathPrefix + ancillaryMeta.dataFileName,
name: filePathPrefix + attachmentMeta.dataFileName,
date: dateUtils.parseDateTime(note.utcDateModified)
});
}

View File

@ -14,7 +14,7 @@ const treeService = require("../tree");
const yauzl = require("yauzl");
const htmlSanitizer = require('../html_sanitizer');
const becca = require("../../becca/becca");
const BNoteAncillary = require("../../becca/entities/bnote_attachment.js");
const BNoteAttachment = require("../../becca/entities/bnote_attachment.js");
/**
* @param {TaskContext} taskContext
@ -65,7 +65,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
};
let parent;
let ancillaryMeta = false;
let attachmentMeta = false;
for (const segment of pathSegments) {
if (!cursor || !cursor.children || cursor.children.length === 0) {
@ -77,10 +77,10 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
if (!cursor) {
for (const file of parent.children) {
for (const ancillary of file.ancillaries || []) {
if (ancillary.dataFileName === segment) {
for (const attachment of file.attachments || []) {
if (attachment.dataFileName === segment) {
cursor = file;
ancillaryMeta = ancillary;
attachmentMeta = attachment;
break;
}
}
@ -95,7 +95,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
return {
parentNoteMeta: parent,
noteMeta: cursor,
ancillaryMeta
attachmentMeta
};
}
@ -370,7 +370,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
}
function saveNote(filePath, content) {
const {parentNoteMeta, noteMeta, ancillaryMeta} = getMeta(filePath);
const {parentNoteMeta, noteMeta, attachmentMeta} = getMeta(filePath);
if (noteMeta?.noImport) {
return;
@ -378,14 +378,14 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
const noteId = getNoteId(noteMeta, filePath);
if (ancillaryMeta) {
const noteAncillary = new BNoteAncillary({
if (attachmentMeta) {
const noteAttachment = new BNoteAttachment({
noteId,
name: ancillaryMeta.name,
mime: ancillaryMeta.mime
name: attachmentMeta.name,
mime: attachmentMeta.mime
});
noteAncillary.setContent(content);
noteAttachment.setContent(content);
return;
}

View File

@ -4,27 +4,27 @@ const log = require("./log");
/**
* @param {BNote} note
*/
function protectNoteAncillaries(note) {
for (const noteAncillary of note.getNoteAncillaries()) {
if (note.isProtected !== noteAncillary.isProtected) {
function protectNoteAttachments(note) {
for (const noteAttachment of note.getNoteAttachments()) {
if (note.isProtected !== noteAttachment.isProtected) {
if (!protectedSession.isProtectedSessionAvailable()) {
log.error("Protected session is not available to fix note ancillaries.");
log.error("Protected session is not available to fix note attachments.");
return;
}
try {
const content = noteAncillary.getContent();
const content = noteAttachment.getContent();
noteAncillary.isProtected = note.isProtected;
noteAttachment.isProtected = note.isProtected;
// this will force de/encryption
noteAncillary.setContent(content);
noteAttachment.setContent(content);
noteAncillary.save();
noteAttachment.save();
}
catch (e) {
log.error(`Could not un/protect note ancillary ID = ${noteAncillary.noteAncillaryId}`);
log.error(`Could not un/protect note attachment ID = ${noteAttachment.noteAttachmentId}`);
throw e;
}
@ -33,5 +33,5 @@ function protectNoteAncillaries(note) {
}
module.exports = {
protectNoteAncillaries
protectNoteAttachments
}

View File

@ -114,7 +114,7 @@ function eraseEntity(entityChange, instanceId) {
"branches",
"attributes",
"note_revisions",
"note_ancillaries",
"note_attachments",
"blobs",
];