diff --git a/bin/tpl/anonymize-database.sql b/bin/tpl/anonymize-database.sql
index cf701e53f..a33c1e3c6 100644
--- a/bin/tpl/anonymize-database.sql
+++ b/bin/tpl/anonymize-database.sql
@@ -1,10 +1,8 @@
UPDATE etapi_tokens SET tokenHash = 'API token hash value';
UPDATE notes SET title = 'title' WHERE noteId != 'root' AND noteId NOT LIKE '\_%' ESCAPE '\';
-UPDATE note_contents SET content = 'text' WHERE content IS NOT NULL;
+UPDATE blobs SET content = 'text' WHERE content IS NOT NULL;
UPDATE note_revisions SET title = 'title';
-UPDATE note_revision_contents SET content = 'text' WHERE content IS NOT NULL;
-UPDATE note_ancillary_contents SET content = 'text' WHERE content IS NOT NULL;
UPDATE attributes SET name = 'name', value = 'value'
WHERE type = 'label'
diff --git a/db/migrations/0217__note_ancillaries.sql b/db/migrations/0217__note_attachments.sql
similarity index 93%
rename from db/migrations/0217__note_ancillaries.sql
rename to db/migrations/0217__note_attachments.sql
index 26b9faa5d..e98ae1045 100644
--- a/db/migrations/0217__note_ancillaries.sql
+++ b/db/migrations/0217__note_attachments.sql
@@ -5,7 +5,6 @@ CREATE TABLE IF NOT EXISTS "note_ancillaries"
name TEXT not null,
mime TEXT not null,
isProtected INT not null DEFAULT 0,
- contentCheckSum TEXT not null,
blobId TEXT not null,
utcDateModified TEXT not null,
isDeleted INT not null,
diff --git a/db/schema.sql b/db/schema.sql
index 6537ea720..bf8225c2e 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -119,13 +119,10 @@ CREATE TABLE IF NOT EXISTS "note_ancillaries"
name TEXT not null,
mime TEXT not null,
isProtected INT not null DEFAULT 0,
- contentCheckSum TEXT not null,
utcDateModified TEXT not null,
isDeleted INT not null,
`deleteId` TEXT DEFAULT NULL);
-CREATE TABLE IF NOT EXISTS "note_ancillary_contents" (`noteAncillaryId` TEXT NOT NULL PRIMARY KEY,
- `content` TEXT DEFAULT NULL,
- `utcDateModified` TEXT NOT NULL);
+
CREATE INDEX IDX_note_ancillaries_name
on note_ancillaries (name);
CREATE UNIQUE INDEX IDX_note_ancillaries_noteId_name
diff --git a/dump-db/inc/dump.js b/dump-db/inc/dump.js
index cd6ba5534..e67d60a1f 100644
--- a/dump-db/inc/dump.js
+++ b/dump-db/inc/dump.js
@@ -74,7 +74,7 @@ function dumpDocument(documentPath, targetPath, options) {
return;
}
- let {content} = sql.getRow("SELECT content FROM note_contents WHERE noteId = ?", [noteId]);
+ let {content} = sql.getRow("SELECT content FROM blobs WHERE blobId = ?", [note.blobId]);
if (content !== null && note.isProtected && dataKey) {
content = decryptService.decrypt(dataKey, content);
diff --git a/src/becca/becca.js b/src/becca/becca.js
index 3f142f35b..f40a40dec 100644
--- a/src/becca/becca.js
+++ b/src/becca/becca.js
@@ -125,7 +125,7 @@ class Becca {
getNoteAncillary(noteAncillaryId) {
const row = sql.getRow("SELECT * FROM note_ancillaries WHERE noteAncillaryId = ?", [noteAncillaryId]);
- const BNoteAncillary = require("./entities/bnote_ancillary"); // avoiding circular dependency problems
+ const BNoteAncillary = require("./entities/bnote_attachment.js"); // avoiding circular dependency problems
return row ? new BNoteAncillary(row) : null;
}
diff --git a/src/becca/entities/bnote.js b/src/becca/entities/bnote.js
index 8561c5c33..4561368b3 100644
--- a/src/becca/entities/bnote.js
+++ b/src/becca/entities/bnote.js
@@ -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_ancillary");
+const BNoteAncillary = require("./bnote_attachment.js");
const TaskContext = require("../../services/task_context");
const dayjs = require("dayjs");
const utc = require('dayjs/plugin/utc');
@@ -1507,13 +1507,6 @@ class BNote extends AbstractBeccaEntity {
saveNoteAncillary(name, mime, content) {
let noteAncillary = this.getNoteAncillaryByName(name);
- if (noteAncillary
- && noteAncillary.mime === mime
- && noteAncillary.contentCheckSum === noteAncillary.calculateCheckSum(content)) {
-
- return noteAncillary; // no change
- }
-
noteAncillary = new BNoteAncillary({
noteId: this.noteId,
name,
diff --git a/src/becca/entities/bnote_ancillary.js b/src/becca/entities/bnote_attachment.js
similarity index 95%
rename from src/becca/entities/bnote_ancillary.js
rename to src/becca/entities/bnote_attachment.js
index 600889391..daf1e063f 100644
--- a/src/becca/entities/bnote_ancillary.js
+++ b/src/becca/entities/bnote_attachment.js
@@ -41,8 +41,6 @@ class BNoteAncillary extends AbstractBeccaEntity {
/** @type {boolean} */
this.isProtected = !!row.isProtected;
/** @type {string} */
- this.contentCheckSum = row.contentCheckSum;
- /** @type {string} */
this.utcDateModified = row.utcDateModified;
}
@@ -91,7 +89,6 @@ class BNoteAncillary extends AbstractBeccaEntity {
setContent(content) {
sql.transactional(() => {
- this.contentCheckSum = this.calculateCheckSum(content);
this.save(); // also explicitly save note_ancillary to update contentCheckSum
const pojo = {
@@ -113,7 +110,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
entityChangesService.addEntityChange({
entityName: 'note_ancillary_contents',
entityId: this.noteAncillaryId,
- hash: this.contentCheckSum,
+ hash: this.contentCheckSum, // FIXME
isErased: false,
utcDateChanged: pojo.utcDateModified,
isSynced: true
@@ -144,7 +141,7 @@ class BNoteAncillary extends AbstractBeccaEntity {
name: this.name,
mime: this.mime,
isProtected: !!this.isProtected,
- contentCheckSum: this.contentCheckSum,
+ contentCheckSum: this.contentCheckSum, // FIXME
isDeleted: false,
utcDateModified: this.utcDateModified
};
diff --git a/src/becca/entity_constructor.js b/src/becca/entity_constructor.js
index 2b2cdf3c7..e4549ef40 100644
--- a/src/becca/entity_constructor.js
+++ b/src/becca/entity_constructor.js
@@ -1,6 +1,6 @@
const BNote = require('./entities/bnote');
const BNoteRevision = require('./entities/bnote_revision');
-const BNoteAncillary = require("./entities/bnote_ancillary");
+const BNoteAncillary = require("./entities/bnote_attachment.js");
const BBranch = require('./entities/bbranch');
const BAttribute = require('./entities/battribute');
const BRecentNote = require('./entities/brecent_note');
@@ -11,11 +11,8 @@ const ENTITY_NAME_TO_ENTITY = {
"attributes": BAttribute,
"branches": BBranch,
"notes": BNote,
- "note_contents": BNote,
"note_revisions": BNoteRevision,
- "note_revision_contents": BNoteRevision,
"note_ancillaries": BNoteAncillary,
- "note_ancillary_contents": BNoteAncillary,
"recent_notes": BRecentNote,
"etapi_tokens": BEtapiToken,
"options": BOption
diff --git a/src/public/app/services/froca_updater.js b/src/public/app/services/froca_updater.js
index cb8a7248b..ab59ee7c2 100644
--- a/src/public/app/services/froca_updater.js
+++ b/src/public/app/services/froca_updater.js
@@ -25,8 +25,6 @@ async function processEntityChanges(entityChanges) {
loadResults.addNoteContent(ec.noteIds, ec.componentId);
} else if (ec.entityName === 'note_revisions') {
loadResults.addNoteRevision(ec.entityId, ec.noteId, ec.componentId);
- } else if (ec.entityName === 'note_revision_contents') {
- // this should change only when toggling isProtected, ignore
} else if (ec.entityName === 'options') {
if (ec.entity.name === 'openTabs') {
continue; // only noise
@@ -36,7 +34,7 @@ async function processEntityChanges(entityChanges) {
loadResults.addOption(ec.entity.name);
}
- else if (['etapi_tokens', 'note_ancillaries', 'note_ancillary_contents'].includes(ec.entityName)) {
+ else if (['etapi_tokens', 'note_ancillaries'].includes(ec.entityName)) {
// NOOP
}
else {
diff --git a/src/public/app/widgets/note_detail.js b/src/public/app/widgets/note_detail.js
index 433a20a71..b146c3f32 100644
--- a/src/public/app/widgets/note_detail.js
+++ b/src/public/app/widgets/note_detail.js
@@ -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/ancillaries.js";
+import AncillariesTypeWidget from "./type_widgets/attachments.js";
const TPL = `
diff --git a/src/public/app/widgets/type_widgets/ancillaries.js b/src/public/app/widgets/type_widgets/attachments.js
similarity index 100%
rename from src/public/app/widgets/type_widgets/ancillaries.js
rename to src/public/app/widgets/type_widgets/attachments.js
diff --git a/src/routes/api/note_revisions.js b/src/routes/api/note_revisions.js
index 7448eb7da..e6eb5079b 100644
--- a/src/routes/api/note_revisions.js
+++ b/src/routes/api/note_revisions.js
@@ -12,9 +12,9 @@ const becca = require("../../becca/becca");
function getNoteRevisions(req) {
return becca.getNoteRevisionsFromQuery(`
SELECT note_revisions.*,
- LENGTH(note_revision_contents.content) AS contentLength
+ LENGTH(blobs.content) AS contentLength
FROM note_revisions
- JOIN note_revision_contents ON note_revisions.noteRevisionId = note_revision_contents.noteRevisionId
+ JOIN blobs ON note_revisions.blobId = blobs.blobId
WHERE noteId = ?
ORDER BY utcDateCreated DESC`, [req.params.noteId]);
}
diff --git a/src/routes/api/stats.js b/src/routes/api/stats.js
index 43aec3014..b342c577c 100644
--- a/src/routes/api/stats.js
+++ b/src/routes/api/stats.js
@@ -4,18 +4,19 @@ const NotFoundError = require("../../errors/not_found_error");
function getNoteSize(req) {
const {noteId} = req.params;
+ const note = becca.getNote(noteId);
const noteSize = sql.getValue(`
SELECT
- COALESCE((SELECT LENGTH(content) FROM note_contents WHERE noteId = ?), 0)
+ COALESCE((SELECT LENGTH(content) FROM blobs WHERE blobId = ?), 0)
+
COALESCE(
(SELECT SUM(LENGTH(content))
FROM note_revisions
- JOIN note_revision_contents USING (noteRevisionId)
+ JOIN blobs USING (blobId)
WHERE note_revisions.noteId = ?),
0
- )`, [noteId, noteId]);
+ )`, [note.blobId, noteId]);
return {
noteSize
@@ -38,14 +39,15 @@ function getSubtreeSize(req) {
SELECT
COALESCE((
SELECT SUM(LENGTH(content))
- FROM note_contents
- JOIN param_list ON param_list.paramId = note_contents.noteId
+ FROM notes
+ JOIN blobs USING (blobId)
+ JOIN param_list ON param_list.paramId = notes.noteId
), 0)
+
COALESCE(
(SELECT SUM(LENGTH(content))
FROM note_revisions
- JOIN note_revision_contents USING (noteRevisionId)
+ JOIN blobs USING (blobId)
JOIN param_list ON param_list.paramId = note_revisions.noteId),
0
)`);
diff --git a/src/routes/api/sync.js b/src/routes/api/sync.js
index 3600aa743..ff50874c6 100644
--- a/src/routes/api/sync.js
+++ b/src/routes/api/sync.js
@@ -12,6 +12,7 @@ const syncOptions = require('../../services/sync_options');
const dateUtils = require('../../services/date_utils');
const utils = require('../../services/utils');
const ws = require('../../services/ws');
+const becca = require("../../becca/becca.js");
async function testSync() {
try {
@@ -85,14 +86,15 @@ function forceFullSync() {
function forceNoteSync(req) {
const noteId = req.params.noteId;
+ const note = becca.getNote(noteId);
const now = dateUtils.utcNowDateTime();
sql.execute(`UPDATE notes SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]);
entityChangesService.moveEntityChangeToTop('notes', noteId);
- sql.execute(`UPDATE note_contents SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]);
- entityChangesService.moveEntityChangeToTop('note_contents', noteId);
+ sql.execute(`UPDATE blobs SET utcDateModified = ? WHERE blobId = ?`, [now, note.blobId]);
+ entityChangesService.moveEntityChangeToTop('blobs', note.blobId);
for (const branchId of sql.getColumn("SELECT branchId FROM branches WHERE noteId = ?", [noteId])) {
sql.execute(`UPDATE branches SET utcDateModified = ? WHERE branchId = ?`, [now, branchId]);
@@ -109,17 +111,11 @@ function forceNoteSync(req) {
for (const noteRevisionId of sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) {
sql.execute(`UPDATE note_revisions SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]);
entityChangesService.moveEntityChangeToTop('note_revisions', noteRevisionId);
-
- sql.execute(`UPDATE note_revision_contents SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]);
- entityChangesService.moveEntityChangeToTop('note_revision_contents', 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);
-
- sql.execute(`UPDATE note_ancillary_contents SET utcDateModified = ? WHERE noteAncillaryId = ?`, [now, noteAncillaryId]);
- entityChangesService.moveEntityChangeToTop('note_ancillary_contents', noteAncillaryId);
}
log.info(`Forcing note sync for ${noteId}`);
diff --git a/src/services/anonymization.js b/src/services/anonymization.js
index e7de0ecc8..db7c2602b 100644
--- a/src/services/anonymization.js
+++ b/src/services/anonymization.js
@@ -14,9 +14,8 @@ function getFullAnonymizationScript() {
const anonymizeScript = `
UPDATE etapi_tokens SET tokenHash = 'API token hash value';
UPDATE notes SET title = 'title' WHERE title NOT IN ('root', '_hidden', '_share');
-UPDATE note_contents SET content = 'text' WHERE content IS NOT NULL;
+UPDATE blobs SET content = 'text' WHERE content IS NOT NULL;
UPDATE note_revisions SET title = 'title';
-UPDATE note_revision_contents SET content = 'text' WHERE content IS NOT NULL;
UPDATE attributes SET name = 'name', value = 'value' WHERE type = 'label' AND name NOT IN(${builtinAttrNames});
UPDATE attributes SET name = 'name' WHERE type = 'relation' AND name NOT IN (${builtinAttrNames});
@@ -34,14 +33,11 @@ VACUUM;
}
function getLightAnonymizationScript() {
- return `
- UPDATE note_contents SET content = 'text' WHERE content IS NOT NULL AND noteId NOT IN (
- SELECT noteId FROM notes WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
- );
- UPDATE note_revision_contents SET content = 'text' WHERE content IS NOT NULL AND noteRevisionId NOT IN (
- SELECT noteRevisionId FROM note_revisions WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
- );
- `;
+ return `UPDATE blobs SET content = 'text' WHERE content IS NOT NULL AND blobId NOT IN (
+ SELECT blobId FROM notes WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
+ UNION ALL
+ SELECT blobId FROM note_revisions WHERE mime IN ('application/javascript;env=backend', 'application/javascript;env=frontend')
+ );`;
}
async function createAnonymizedCopy(type) {
diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js
index 696a89c49..133e5af85 100644
--- a/src/services/consistency_checks.js
+++ b/src/services/consistency_checks.js
@@ -656,11 +656,9 @@ class ConsistencyChecks {
findEntityChangeIssues() {
this.runEntityChangeChecks("notes", "noteId");
- //this.runEntityChangeChecks("note_contents", "noteId");
this.runEntityChangeChecks("note_revisions", "noteRevisionId");
- //this.runEntityChangeChecks("note_revision_contents", "noteRevisionId");
this.runEntityChangeChecks("note_ancillaries", "noteAncillaryId");
- //this.runEntityChangeChecks("note_ancillary_contents", "noteAncillaryId");
+ this.runEntityChangeChecks("blobs", "blobId");
this.runEntityChangeChecks("branches", "branchId");
this.runEntityChangeChecks("attributes", "attributeId");
this.runEntityChangeChecks("etapi_tokens", "etapiTokenId");
diff --git a/src/services/entity_changes.js b/src/services/entity_changes.js
index 2c3991d81..c91dc19dd 100644
--- a/src/services/entity_changes.js
+++ b/src/services/entity_changes.js
@@ -104,7 +104,7 @@ function fillEntityChanges(entityName, entityPrimaryKey, condition = '') {
let utcDateChanged;
let isSynced;
- if (entityName.endsWith("_contents")) {
+ if (entityName === 'blobs') {
// FIXME: hacky, not sure if it might cause some problems
hash = "fake value";
utcDateChanged = dateUtils.utcNowDateTime();
@@ -147,12 +147,10 @@ function fillAllEntityChanges() {
sql.execute("DELETE FROM entity_changes WHERE isErased = 0");
fillEntityChanges("notes", "noteId");
- fillEntityChanges("note_contents", "noteId");
fillEntityChanges("branches", "branchId");
fillEntityChanges("note_revisions", "noteRevisionId");
- fillEntityChanges("note_revision_contents", "noteRevisionId");
fillEntityChanges("note_ancillaries", "noteAncillaryId");
- fillEntityChanges("note_ancillary_contents", "noteAncillaryId");
+ fillEntityChanges("blobs", "blobId");
fillEntityChanges("attributes", "attributeId");
fillEntityChanges("etapi_tokens", "etapiTokenId");
fillEntityChanges("options", "name", 'isSynced = 1');
diff --git a/src/services/handlers.js b/src/services/handlers.js
index 4bb21f910..69e3c1e21 100644
--- a/src/services/handlers.js
+++ b/src/services/handlers.js
@@ -59,7 +59,7 @@ eventService.subscribe([ eventService.ENTITY_CHANGED, eventService.ENTITY_DELETE
});
eventService.subscribe(eventService.ENTITY_CHANGED, ({entityName, entity}) => {
- if (entityName === 'note_contents') {
+ if (entityName === 'note_contents') { // FIXME
runAttachedRelations(entity, 'runOnNoteContentChange', entity);
}
});
diff --git a/src/services/import/enex.js b/src/services/import/enex.js
index 5e8eab780..d0199bbdb 100644
--- a/src/services/import/enex.js
+++ b/src/services/import/enex.js
@@ -206,7 +206,7 @@ function importEnex(taskContext, file, parentNote) {
}
});
- function updateDates(noteId, utcDateCreated, utcDateModified) {
+ function updateDates(note, utcDateCreated, utcDateModified) {
// it's difficult to force custom dateCreated and dateModified to Note entity, so we do it post-creation with SQL
sql.execute(`
UPDATE notes
@@ -215,13 +215,13 @@ function importEnex(taskContext, file, parentNote) {
dateModified = ?,
utcDateModified = ?
WHERE noteId = ?`,
- [utcDateCreated, utcDateCreated, utcDateModified, utcDateModified, noteId]);
+ [utcDateCreated, utcDateCreated, utcDateModified, utcDateModified, note.noteId]);
sql.execute(`
- UPDATE note_contents
+ UPDATE blobs
SET utcDateModified = ?
- WHERE noteId = ?`,
- [utcDateModified, noteId]);
+ WHERE blobId = ?`,
+ [utcDateModified, note.blobId]);
}
function saveNote() {
@@ -287,7 +287,7 @@ function importEnex(taskContext, file, parentNote) {
resourceNote.addAttribute(attr.type, attr.name, attr.value);
}
- updateDates(resourceNote.noteId, utcDateCreated, utcDateModified);
+ updateDates(resourceNote, utcDateCreated, utcDateModified);
taskContext.increaseProgressCount();
@@ -310,7 +310,7 @@ function importEnex(taskContext, file, parentNote) {
}
}
- updateDates(imageNote.noteId, utcDateCreated, utcDateModified);
+ updateDates(imageNote, utcDateCreated, utcDateModified);
const imageLink = `

`;
@@ -337,7 +337,7 @@ function importEnex(taskContext, file, parentNote) {
noteService.asyncPostProcessContent(noteEntity, content);
- updateDates(noteEntity.noteId, utcDateCreated, utcDateModified);
+ updateDates(noteEntity, utcDateCreated, utcDateModified);
}
saxStream.on("closetag", tag => {
diff --git a/src/services/import/zip.js b/src/services/import/zip.js
index 64df89e28..33a6cbe77 100644
--- a/src/services/import/zip.js
+++ b/src/services/import/zip.js
@@ -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_ancillary");
+const BNoteAncillary = require("../../becca/entities/bnote_attachment.js");
/**
* @param {TaskContext} taskContext
diff --git a/src/services/note_ancillaries.js b/src/services/note_attachments.js
similarity index 100%
rename from src/services/note_ancillaries.js
rename to src/services/note_attachments.js
diff --git a/src/services/note_revisions.js b/src/services/note_revisions.js
index 977e80a77..012884c4c 100644
--- a/src/services/note_revisions.js
+++ b/src/services/note_revisions.js
@@ -44,9 +44,6 @@ function eraseNoteRevisions(noteRevisionIdsToErase) {
sql.executeMany(`DELETE FROM note_revisions WHERE noteRevisionId IN (???)`, noteRevisionIdsToErase);
sql.executeMany(`UPDATE entity_changes SET isErased = 1 WHERE entityName = 'note_revisions' AND entityId IN (???)`, noteRevisionIdsToErase);
-
- sql.executeMany(`DELETE FROM note_revision_contents WHERE noteRevisionId IN (???)`, noteRevisionIdsToErase);
- sql.executeMany(`UPDATE entity_changes SET isErased = 1 WHERE entityName = 'note_revision_contents' AND entityId IN (???)`, noteRevisionIdsToErase);
}
module.exports = {
diff --git a/src/services/notes.js b/src/services/notes.js
index 2c71a9a08..9d6260cfd 100644
--- a/src/services/notes.js
+++ b/src/services/notes.js
@@ -220,7 +220,7 @@ function createNewNote(params) {
entity: note
});
- eventService.emit(eventService.ENTITY_CREATED, {
+ eventService.emit(eventService.ENTITY_CREATED, { // FIXME
entityName: 'note_contents',
entity: note
});
@@ -499,7 +499,7 @@ function downloadImages(noteId, content) {
asyncPostProcessContent(origNote, updatedContent);
eventService.emit(eventService.ENTITY_CHANGED, {
- entityName: 'note_contents',
+ entityName: 'note_contents', // FIXME
entity: origNote
});
@@ -733,9 +733,6 @@ function eraseNotes(noteIdsToErase) {
sql.executeMany(`DELETE FROM notes WHERE noteId IN (???)`, noteIdsToErase);
setEntityChangesAsErased(sql.getManyRows(`SELECT * FROM entity_changes WHERE entityName = 'notes' AND entityId IN (???)`, noteIdsToErase));
- sql.executeMany(`DELETE FROM note_contents WHERE noteId IN (???)`, noteIdsToErase);
- setEntityChangesAsErased(sql.getManyRows(`SELECT * FROM entity_changes WHERE entityName = 'note_contents' AND entityId IN (???)`, noteIdsToErase));
-
// we also need to erase all "dependent" entities of the erased notes
const branchIdsToErase = sql.getManyRows(`SELECT branchId FROM branches WHERE noteId IN (???)`, noteIdsToErase)
.map(row => row.branchId);
diff --git a/src/services/search/expressions/note_content_fulltext.js b/src/services/search/expressions/note_content_fulltext.js
index 456306667..2476754d1 100644
--- a/src/services/search/expressions/note_content_fulltext.js
+++ b/src/services/search/expressions/note_content_fulltext.js
@@ -42,7 +42,7 @@ class NoteContentFulltextExp extends Expression {
for (const row of sql.iterateRows(`
SELECT noteId, type, mime, content, isProtected
- FROM notes JOIN note_contents USING (noteId)
+ FROM notes JOIN blobs USING (blobId)
WHERE type IN ('text', 'code', 'mermaid') AND isDeleted = 0`)) {
this.findInText(row, inputNoteSet, resultNoteSet);
diff --git a/src/services/search/services/search.js b/src/services/search/services/search.js
index 80b49f3bb..c633d4189 100644
--- a/src/services/search/services/search.js
+++ b/src/services/search/services/search.js
@@ -103,7 +103,7 @@ function loadNeededInfoFromDatabase() {
noteId,
LENGTH(content) AS length
FROM notes
- JOIN note_contents USING(noteId)
+ JOIN blobs USING(blobId)
WHERE notes.isDeleted = 0`);
for (const {noteId, length} of noteContentLengths) {
@@ -122,7 +122,7 @@ function loadNeededInfoFromDatabase() {
LENGTH(content) AS length
FROM notes
JOIN note_revisions USING(noteId)
- JOIN note_revision_contents USING(noteRevisionId)
+ JOIN blobs USING(blobId)
WHERE notes.isDeleted = 0`);
for (const {noteId, length} of noteRevisionContentLengths) {
diff --git a/src/services/sync.js b/src/services/sync.js
index 243266cf6..77622d6ce 100644
--- a/src/services/sync.js
+++ b/src/services/sync.js
@@ -321,7 +321,7 @@ function getEntityChangeRow(entityName, entityId) {
throw new Error(`Entity ${entityName} ${entityId} not found.`);
}
- if (['note_contents', 'note_revision_contents', 'note_ancillary_contents'].includes(entityName) && entity.content !== null) {
+ if (entityName === 'blobs' && entity.content !== null) {
if (typeof entity.content === 'string') {
entity.content = Buffer.from(entity.content, 'UTF-8');
}
diff --git a/src/services/sync_update.js b/src/services/sync_update.js
index 50fb29a0e..5bd467ddb 100644
--- a/src/services/sync_update.js
+++ b/src/services/sync_update.js
@@ -64,7 +64,7 @@ function updateNormalEntity(remoteEntityChange, remoteEntityRow, instanceId) {
|| localEntityChange.utcDateChanged < remoteEntityChange.utcDateChanged
|| localEntityChange.hash !== remoteEntityChange.hash // sync error, we should still update
) {
- if (['note_contents', 'note_revision_contents', 'note_ancillary_contents'].includes(remoteEntityChange.entityName)) {
+ if (remoteEntityChange.entityName === 'blobs') {
remoteEntityRow.content = handleContent(remoteEntityRow.content);
}
@@ -94,7 +94,7 @@ function updateNoteReordering(entityChange, entity, instanceId) {
function handleContent(content) {
// we always use Buffer object which is different from normal saving - there we use simple string type for
- // "string notes". The problem is that in general it's not possible to detect whether a note_content
+ // "string notes". The problem is that in general it's not possible to detect whether a blob content
// is string note or note (syncs can arrive out of order)
content = content === null ? null : Buffer.from(content, 'base64');
@@ -111,13 +111,11 @@ function eraseEntity(entityChange, instanceId) {
const entityNames = [
"notes",
- "note_contents",
"branches",
"attributes",
"note_revisions",
- "note_revision_contents",
"note_ancillaries",
- "note_ancillary_contents"
+ "blobs",
];
if (!entityNames.includes(entityName)) {
diff --git a/src/services/ws.js b/src/services/ws.js
index 8c1f34dd4..ac054b8f4 100644
--- a/src/services/ws.js
+++ b/src/services/ws.js
@@ -147,13 +147,13 @@ function fillInAdditionalProperties(entityChange) {
// entities with higher number can reference the entities with lower number
const ORDERING = {
"etapi_tokens": 0,
- "attributes": 1,
- "branches": 1,
- "note_contents": 1,
- "note_reordering": 1,
- "note_revision_contents": 2,
- "note_revisions": 1,
- "notes": 0,
+ "attributes": 2,
+ "branches": 2,
+ "blobs": 0,
+ "note_reordering": 2,
+ "note_revisions": 2,
+ "note_attachments": 3,
+ "notes": 1,
"options": 0
};
diff --git a/src/share/shaca/entities/snote.js b/src/share/shaca/entities/snote.js
index e083ca97b..4a80e0157 100644
--- a/src/share/shaca/entities/snote.js
+++ b/src/share/shaca/entities/snote.js
@@ -12,7 +12,7 @@ const CREDENTIALS = 'shareCredentials';
const isCredentials = attr => attr.type === 'label' && attr.name === CREDENTIALS;
class SNote extends AbstractShacaEntity {
- constructor([noteId, title, type, mime, utcDateModified, isProtected]) {
+ constructor([noteId, title, type, mime, blobId, utcDateModified, isProtected]) {
super();
/** @param {string} */
@@ -24,6 +24,8 @@ class SNote extends AbstractShacaEntity {
/** @param {string} */
this.mime = mime;
/** @param {string} */
+ this.blobId = blobId;
+ /** @param {string} */
this.utcDateModified = utcDateModified; // used for caching of images
/** @param {boolean} */
this.isProtected = isProtected;
@@ -92,14 +94,14 @@ class SNote extends AbstractShacaEntity {
}
getContent(silentNotFoundError = false) {
- const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
+ const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]);
if (!row) {
if (silentNotFoundError) {
return undefined;
}
else {
- throw new Error(`Cannot find note content for noteId=${this.noteId}`);
+ throw new Error(`Cannot find note content for noteId '${this.noteId}', blobId '${this.blobId}'`);
}
}
diff --git a/src/share/shaca/shaca_loader.js b/src/share/shaca/shaca_loader.js
index 64c488036..7ecaaf617 100644
--- a/src/share/shaca/shaca_loader.js
+++ b/src/share/shaca/shaca_loader.js
@@ -35,7 +35,7 @@ function load() {
const noteIdStr = noteIds.map(noteId => `'${noteId}'`).join(",");
const rawNoteRows = sql.getRawRows(`
- SELECT noteId, title, type, mime, utcDateModified, isProtected
+ SELECT noteId, title, type, mime, blobId, utcDateModified, isProtected
FROM notes
WHERE isDeleted = 0
AND noteId IN (${noteIdStr})`);