mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
many changes related to #1192:
- use CSS contain wherever possible to reduce subtrees of forced reflows - reduced dependency between note and note_contents updates which will reduce number of updates to components - optimization of "many rows" querying
This commit is contained in:
parent
c20577909c
commit
53b39e2e82
55
db/migrations/0165__move_contentLength.sql
Normal file
55
db/migrations/0165__move_contentLength.sql
Normal file
@ -0,0 +1,55 @@
|
||||
CREATE TABLE IF NOT EXISTS "notes_mig" (
|
||||
`noteId` TEXT NOT NULL,
|
||||
`title` TEXT NOT NULL DEFAULT "note",
|
||||
`isProtected` INT NOT NULL DEFAULT 0,
|
||||
`type` TEXT NOT NULL DEFAULT 'text',
|
||||
`mime` TEXT NOT NULL DEFAULT 'text/html',
|
||||
`hash` TEXT DEFAULT "" NOT NULL,
|
||||
`isDeleted` INT NOT NULL DEFAULT 0,
|
||||
`deleteId` TEXT DEFAULT NULL,
|
||||
`isErased` INT NOT NULL DEFAULT 0,
|
||||
`dateCreated` TEXT NOT NULL,
|
||||
`dateModified` TEXT NOT NULL,
|
||||
`utcDateCreated` TEXT NOT NULL,
|
||||
`utcDateModified` TEXT NOT NULL,
|
||||
PRIMARY KEY(`noteId`));
|
||||
|
||||
INSERT INTO notes_mig (noteId, title, isProtected, type, mime, hash, isDeleted, deleteId, isErased, dateCreated, dateModified, utcDateCreated, utcDateModified)
|
||||
SELECT noteId, title, isProtected, type, mime, hash, isDeleted, deleteId, isErased, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes;
|
||||
|
||||
DROP TABLE notes;
|
||||
ALTER TABLE notes_mig RENAME TO notes;
|
||||
|
||||
CREATE INDEX `IDX_notes_isDeleted` ON `notes` (`isDeleted`);
|
||||
CREATE INDEX `IDX_notes_title` ON `notes` (`title`);
|
||||
CREATE INDEX `IDX_notes_type` ON `notes` (`type`);
|
||||
CREATE INDEX `IDX_notes_dateCreated` ON `notes` (`dateCreated`);
|
||||
CREATE INDEX `IDX_notes_dateModified` ON `notes` (`dateModified`);
|
||||
CREATE INDEX `IDX_notes_utcDateModified` ON `notes` (`utcDateModified`);
|
||||
CREATE INDEX `IDX_notes_utcDateCreated` ON `notes` (`utcDateCreated`);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "note_revisions_mig" (`noteRevisionId` TEXT NOT NULL PRIMARY KEY,
|
||||
`noteId` TEXT NOT NULL,
|
||||
`title` TEXT,
|
||||
`isErased` INT NOT NULL DEFAULT 0,
|
||||
`isProtected` INT NOT NULL DEFAULT 0,
|
||||
`utcDateLastEdited` TEXT NOT NULL,
|
||||
`utcDateCreated` TEXT NOT NULL,
|
||||
`utcDateModified` TEXT NOT NULL,
|
||||
`dateLastEdited` TEXT NOT NULL,
|
||||
`dateCreated` TEXT NOT NULL,
|
||||
type TEXT DEFAULT '' NOT NULL,
|
||||
mime TEXT DEFAULT '' NOT NULL,
|
||||
hash TEXT DEFAULT '' NOT NULL);
|
||||
|
||||
INSERT INTO note_revisions_mig (noteRevisionId, noteId, title, isErased, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, type, mime, hash)
|
||||
SELECT noteRevisionId, noteId, title, isErased, isProtected, utcDateLastEdited, utcDateCreated, utcDateModified, dateLastEdited, dateCreated, type, mime, hash FROM note_revisions;
|
||||
|
||||
DROP TABLE note_revisions;
|
||||
ALTER TABLE note_revisions_mig RENAME TO note_revisions;
|
||||
|
||||
CREATE INDEX `IDX_note_revisions_noteId` ON `note_revisions` (`noteId`);
|
||||
CREATE INDEX `IDX_note_revisions_utcDateCreated` ON `note_revisions` (`utcDateCreated`);
|
||||
CREATE INDEX `IDX_note_revisions_utcDateLastEdited` ON `note_revisions` (`utcDateLastEdited`);
|
||||
CREATE INDEX `IDX_note_revisions_dateCreated` ON `note_revisions` (`dateCreated`);
|
||||
CREATE INDEX `IDX_note_revisions_dateLastEdited` ON `note_revisions` (`dateLastEdited`);
|
20
db/migrations/0166__add_dateModified_to_note_content.sql
Normal file
20
db/migrations/0166__add_dateModified_to_note_content.sql
Normal file
@ -0,0 +1,20 @@
|
||||
CREATE TABLE IF NOT EXISTS "note_contents_mig" (
|
||||
`noteId` TEXT NOT NULL,
|
||||
`content` TEXT NULL DEFAULT NULL,
|
||||
`hash` TEXT DEFAULT "" NOT NULL,
|
||||
`dateModified` TEXT NOT NULL,
|
||||
`utcDateModified` TEXT NOT NULL,
|
||||
PRIMARY KEY(`noteId`)
|
||||
);
|
||||
|
||||
INSERT INTO note_contents_mig (noteId, content, hash, dateModified, utcDateModified)
|
||||
SELECT noteId,
|
||||
content,
|
||||
hash,
|
||||
(SELECT dateModified FROM notes WHERE noteId = note_contents.noteId),
|
||||
utcDateModified
|
||||
FROM note_contents;
|
||||
|
||||
DROP TABLE note_contents;
|
||||
|
||||
ALTER TABLE note_contents_mig RENAME TO note_contents;
|
@ -26,14 +26,7 @@ class Entity {
|
||||
const origHash = this.hash;
|
||||
|
||||
this.hash = this.generateHash();
|
||||
|
||||
if (this.forcedChange) {
|
||||
this.isChanged = true;
|
||||
delete this.forcedChange;
|
||||
}
|
||||
else {
|
||||
this.isChanged = origHash !== this.hash;
|
||||
}
|
||||
this.isChanged = origHash !== this.hash;
|
||||
}
|
||||
|
||||
generateIdIfNecessary() {
|
||||
|
@ -20,7 +20,6 @@ const RELATION_DEFINITION = 'relation-definition';
|
||||
* @property {string} type - one of "text", "code", "file" or "render"
|
||||
* @property {string} mime - MIME type, e.g. "text/html"
|
||||
* @property {string} title - note title
|
||||
* @property {int} contentLength - length of content
|
||||
* @property {boolean} isProtected - true if note is protected
|
||||
* @property {boolean} isDeleted - true if note is deleted
|
||||
* @property {string|null} deleteId - ID identifying delete transaction
|
||||
@ -106,6 +105,16 @@ class Note extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
getContentMetadata() {
|
||||
return sql.getRow(`
|
||||
SELECT
|
||||
LENGTH(content) AS contentLength,
|
||||
dateModified,
|
||||
utcDateModified
|
||||
FROM note_contents
|
||||
WHERE noteId = ?`, [this.noteId]);
|
||||
}
|
||||
|
||||
/** @returns {*} */
|
||||
getJsonContent() {
|
||||
const content = this.getContent();
|
||||
@ -129,16 +138,12 @@ class Note extends Entity {
|
||||
content = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
||||
}
|
||||
|
||||
// force updating note itself so that dateModified is represented correctly even for the content
|
||||
this.forcedChange = true;
|
||||
this.contentLength = content.byteLength;
|
||||
this.save();
|
||||
|
||||
this.content = content;
|
||||
|
||||
const pojo = {
|
||||
noteId: this.noteId,
|
||||
content: content,
|
||||
dateModified: dateUtils.localNowDateTime(),
|
||||
utcDateModified: dateUtils.utcNowDateTime(),
|
||||
hash: utils.hash(this.noteId + "|" + content.toString())
|
||||
};
|
||||
@ -903,10 +908,6 @@ class Note extends Entity {
|
||||
this.utcDateCreated = dateUtils.utcNowDateTime();
|
||||
}
|
||||
|
||||
if (this.contentLength === undefined) {
|
||||
this.contentLength = -1;
|
||||
}
|
||||
|
||||
super.beforeSaving();
|
||||
|
||||
if (this.isChanged) {
|
||||
|
@ -15,7 +15,6 @@ const entityChangesService = require('../services/entity_changes.js');
|
||||
* @property {string} type
|
||||
* @property {string} mime
|
||||
* @property {string} title
|
||||
* @property {int} contentLength
|
||||
* @property {boolean} isErased
|
||||
* @property {boolean} isProtected
|
||||
* @property {string} dateLastEdited
|
||||
@ -29,7 +28,7 @@ const entityChangesService = require('../services/entity_changes.js');
|
||||
class NoteRevision extends Entity {
|
||||
static get entityName() { return "note_revisions"; }
|
||||
static get primaryKeyName() { return "noteRevisionId"; }
|
||||
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "contentLength", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
|
||||
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
|
||||
|
||||
constructor(row) {
|
||||
super(row);
|
||||
@ -101,11 +100,6 @@ class NoteRevision extends Entity {
|
||||
}
|
||||
|
||||
setContent(content) {
|
||||
// force updating note itself so that utcDateModified is represented correctly even for the content
|
||||
this.forcedChange = true;
|
||||
this.contentLength = content === null ? 0 : content.length;
|
||||
this.save();
|
||||
|
||||
this.content = content;
|
||||
|
||||
const pojo = {
|
||||
|
@ -6,9 +6,14 @@ class NoteComplement {
|
||||
/** @param {string} */
|
||||
this.noteId = row.noteId;
|
||||
|
||||
/** @param {string} */
|
||||
/**
|
||||
* @param {string} - can either contain the whole content (in e.g. string notes), only part (large text notes) or nothing at all (binary notes, images)
|
||||
*/
|
||||
this.content = row.content;
|
||||
|
||||
/** @param {int} */
|
||||
this.contentLength = row.contentLength;
|
||||
|
||||
/** @param {string} */
|
||||
this.dateCreated = row.dateCreated;
|
||||
|
||||
@ -20,7 +25,13 @@ class NoteComplement {
|
||||
|
||||
/** @param {string} */
|
||||
this.utcDateModified = row.utcDateModified;
|
||||
|
||||
/** @param {string} */
|
||||
this.combinedDateModified = row.combinedDateModified;
|
||||
|
||||
/** @param {string} */
|
||||
this.combinedUtcDateModified = row.combinedUtcDateModified;
|
||||
}
|
||||
}
|
||||
|
||||
export default NoteComplement;
|
||||
export default NoteComplement;
|
||||
|
@ -45,8 +45,6 @@ class NoteShort {
|
||||
this.noteId = row.noteId;
|
||||
/** @param {string} */
|
||||
this.title = row.title;
|
||||
/** @param {int} */
|
||||
this.contentLength = row.contentLength;
|
||||
/** @param {boolean} */
|
||||
this.isProtected = !!row.isProtected;
|
||||
/** @param {string} one of 'text', 'code', 'file' or 'render' */
|
||||
|
@ -110,6 +110,7 @@ export default class DesktopMainWindowLayout {
|
||||
.id('root-widget')
|
||||
.css('height', '100vh')
|
||||
.child(new FlexContainer('row')
|
||||
.css('height', '35px')
|
||||
.child(new GlobalMenuWidget())
|
||||
.child(new TabRowWidget())
|
||||
.child(new TitleBarButtonsWidget()))
|
||||
@ -130,6 +131,7 @@ export default class DesktopMainWindowLayout {
|
||||
.child(new FlexContainer('column').id('center-pane')
|
||||
.child(new FlexContainer('row').class('title-row')
|
||||
.cssBlock('.title-row > * { margin: 5px; }')
|
||||
.css('height', '55px')
|
||||
.child(new NoteTitleWidget())
|
||||
.child(new RunScriptButtonsWidget().hideInZenMode())
|
||||
.child(new NoteTypeWidget().hideInZenMode())
|
||||
|
@ -120,4 +120,11 @@ export default class LoadResults {
|
||||
&& this.contentNoteIdToSourceId.length === 0
|
||||
&& this.options.length === 0;
|
||||
}
|
||||
|
||||
isEmptyForTree() {
|
||||
return Object.keys(this.noteIdToSourceId).length === 0
|
||||
&& this.branches.length === 0
|
||||
&& this.attributes.length === 0
|
||||
&& this.noteReorderings.length === 0;
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ export default class AttributeEditorWidget extends TabAwareWidget {
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
this.$editor = this.$widget.find('.attribute-list-editor');
|
||||
|
||||
this.initialized = this.initEditor();
|
||||
|
@ -116,6 +116,7 @@ export default class AttributeListWidget extends TabAwareWidget {
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
this.$promotedExpander = this.$widget.find('.attr-promoted-expander');
|
||||
this.$allAttrWrapper = this.$widget.find('.all-attr-wrapper');
|
||||
|
@ -25,6 +25,11 @@ class BasicWidget extends Component {
|
||||
return this;
|
||||
}
|
||||
|
||||
contentSized() {
|
||||
this.css('contain', 'layout paint');
|
||||
return this;
|
||||
}
|
||||
|
||||
collapsible() {
|
||||
this.css('min-height', '0');
|
||||
return this;
|
||||
|
@ -29,6 +29,7 @@ export default class CollapsibleWidget extends TabAwareWidget {
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(WIDGET_TPL);
|
||||
this.contentSized();
|
||||
this.$widget.find('[data-target]').attr('data-target', "#" + this.componentId);
|
||||
|
||||
this.$bodyWrapper = this.$widget.find('.body-wrapper');
|
||||
|
@ -64,8 +64,8 @@ export default class NoteInfoWidget extends CollapsibleWidget {
|
||||
.attr("title", noteComplement.dateCreated);
|
||||
|
||||
this.$dateModified
|
||||
.text(noteComplement.dateModified.substr(0, 16))
|
||||
.attr("title", noteComplement.dateCreated);
|
||||
.text(noteComplement.combinedDateModified.substr(0, 16))
|
||||
.attr("title", noteComplement.combinedDateModified);
|
||||
|
||||
this.$type.text(note.type);
|
||||
|
||||
@ -78,7 +78,7 @@ export default class NoteInfoWidget extends CollapsibleWidget {
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.isNoteReloaded(this.noteId)) {
|
||||
if (loadResults.isNoteReloaded(this.noteId) || loadResults.isNoteContentReloaded(this.noteId)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
@ -78,4 +78,4 @@ class NoteRevisionsWidget extends CollapsibleWidget {
|
||||
}
|
||||
}
|
||||
|
||||
export default NoteRevisionsWidget;
|
||||
export default NoteRevisionsWidget;
|
||||
|
@ -32,8 +32,9 @@ const WIDGET_TPL = `
|
||||
|
||||
class GlobalButtonsWidget extends BasicWidget {
|
||||
doRender() {
|
||||
return this.$widget = $(WIDGET_TPL);
|
||||
this.$widget = $(WIDGET_TPL);
|
||||
this.contentSized();
|
||||
}
|
||||
}
|
||||
|
||||
export default GlobalButtonsWidget;
|
||||
export default GlobalButtonsWidget;
|
||||
|
@ -104,6 +104,7 @@ const TPL = `
|
||||
export default class GlobalMenuWidget extends BasicWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
this.$widget.find(".show-about-dialog-button").on('click',
|
||||
() => import("../dialogs/about.js").then(d => d.showDialog()));
|
||||
|
@ -23,6 +23,7 @@ export default class HistoryNavigationWidget extends BasicWidget {
|
||||
doRender() {
|
||||
if (utils.isElectron()) {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
const contextMenuHandler = e => {
|
||||
e.preventDefault();
|
||||
|
@ -93,6 +93,7 @@ const TPL = `
|
||||
export default class NoteActionsWidget extends TabAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
this.$showSourceButton = this.$widget.find('.show-source-button');
|
||||
|
||||
|
@ -50,6 +50,7 @@ const TPL = `
|
||||
export default class NotePathsWidget extends TabAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
this.$currentPath = this.$widget.find('.current-path');
|
||||
this.$dropdown = this.$widget.find(".dropdown");
|
||||
|
@ -957,6 +957,10 @@ export default class NoteTreeWidget extends TabAwareWidget {
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({loadResults}) {
|
||||
if (loadResults.isEmptyForTree()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeNode = this.getActiveNode();
|
||||
const activeNodeFocused = activeNode && activeNode.hasFocus();
|
||||
const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null;
|
||||
|
@ -34,6 +34,7 @@ const TPL = `
|
||||
export default class NoteTypeWidget extends TabAwareWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
this.$widget.on('show.bs.dropdown', () => this.renderDropdown());
|
||||
|
||||
|
@ -43,6 +43,8 @@ export default class SidePaneToggles extends BasicWidget {
|
||||
|
||||
this.$widget.find(".show-left-pane-button").on('click', () => this.toggleAndSave('left', true));
|
||||
this.$widget.find(".hide-left-pane-button").on('click', () => this.toggleAndSave('left', false));
|
||||
|
||||
this.$widget.css("contain", "none"); // this widget overflows so we need to override default containment
|
||||
}
|
||||
|
||||
toggleSidebar(side, show) {
|
||||
|
@ -10,6 +10,7 @@ const TPL = `
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 4px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.standard-top-widget button {
|
||||
@ -87,4 +88,4 @@ export default class StandardTopWidget extends BasicWidget {
|
||||
this.$enterProtectedSessionButton.hide();
|
||||
this.$leaveProtectedSessionButton.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ export default class TitleBarButtonsWidget extends BasicWidget {
|
||||
}
|
||||
|
||||
this.$widget = $(TPL);
|
||||
this.contentSized();
|
||||
|
||||
const $minimizeBtn = this.$widget.find(".minimize-btn");
|
||||
const $maximizeBtn = this.$widget.find(".maximize-btn");
|
||||
|
@ -126,11 +126,11 @@ export default class FileTypeWidget extends TypeWidget {
|
||||
|
||||
this.$fileNoteId.text(note.noteId);
|
||||
this.$fileName.text(attributeMap.originalFileName || "?");
|
||||
this.$fileSize.text(note.contentLength + " bytes");
|
||||
this.$fileType.text(note.mime);
|
||||
|
||||
const noteComplement = await this.tabContext.getNoteComplement();
|
||||
|
||||
this.$fileSize.text(noteComplement.contentLength + " bytes");
|
||||
this.$previewContent.empty().hide();
|
||||
this.$pdfPreview.attr('src', '').empty().hide();
|
||||
|
||||
|
@ -127,8 +127,10 @@ class ImageTypeWidget extends TypeWidget {
|
||||
|
||||
this.$widget.show();
|
||||
|
||||
const noteComplement = await this.tabContext.getNoteComplement();
|
||||
|
||||
this.$fileName.text(attributeMap.originalFileName || "?");
|
||||
this.$fileSize.text(note.contentLength + " bytes");
|
||||
this.$fileSize.text(noteComplement.contentLength + " bytes");
|
||||
this.$fileType.text(note.mime);
|
||||
|
||||
const imageHash = utils.randomString(10);
|
||||
|
@ -635,6 +635,10 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.component {
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.toast {
|
||||
background-color: var(--accented-background-color) !important;
|
||||
color: var(--main-text-color) !important;
|
||||
|
@ -9,8 +9,12 @@ const path = require('path');
|
||||
|
||||
function getNoteRevisions(req) {
|
||||
return repository.getEntities(`
|
||||
SELECT * FROM note_revisions
|
||||
WHERE noteId = ? AND isErased = 0
|
||||
SELECT note_revisions.*,
|
||||
LENGTH(note_revision_contents.content) AS contentLength
|
||||
FROM note_revisions
|
||||
JOIN note_revision_contents ON note_revisions.noteRevisionId = note_revision_contents.noteRevisionId
|
||||
WHERE noteId = ?
|
||||
AND isErased = 0
|
||||
ORDER BY utcDateCreated DESC`, [req.params.noteId]);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,11 @@ function getNote(req) {
|
||||
}
|
||||
}
|
||||
|
||||
const contentMetadata = note.getContentMetadata();
|
||||
|
||||
note.combinedUtcDateModified = note.utcDateModified > contentMetadata.utcDateModified ? note.utcDateModified : contentMetadata.utcDateModified;
|
||||
note.combinedDateModified = note.utcDateModified > contentMetadata.utcDateModified ? note.dateModified : contentMetadata.dateModified;
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@ const build = require('./build');
|
||||
const packageJson = require('../../package');
|
||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||
|
||||
const APP_DB_VERSION = 164;
|
||||
const SYNC_VERSION = 15;
|
||||
const APP_DB_VERSION = 166;
|
||||
const SYNC_VERSION = 16;
|
||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||
|
||||
module.exports = {
|
||||
|
@ -14,8 +14,6 @@ class Note {
|
||||
this.type = row.type;
|
||||
/** @param {string} */
|
||||
this.mime = row.mime;
|
||||
/** @param {number} */
|
||||
this.contentLength = row.contentLength;
|
||||
/** @param {string} */
|
||||
this.dateCreated = row.dateCreated;
|
||||
/** @param {string} */
|
||||
@ -182,8 +180,6 @@ class Note {
|
||||
}
|
||||
|
||||
this.flatTextCache = this.flatTextCache.toLowerCase();
|
||||
|
||||
console.log(this.flatTextCache);
|
||||
}
|
||||
|
||||
return this.flatTextCache;
|
||||
|
@ -15,7 +15,7 @@ sqlInit.dbReady.then(() => {
|
||||
function load() {
|
||||
noteCache.reset();
|
||||
|
||||
for (const row of sql.iterateRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified, contentLength FROM notes WHERE isDeleted = 0`, [])) {
|
||||
for (const row of sql.iterateRows(`SELECT noteId, title, type, mime, isProtected, dateCreated, dateModified, utcDateCreated, utcDateModified FROM notes WHERE isDeleted = 0`, [])) {
|
||||
new Note(noteCache, row);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@ function createNoteRevision(note) {
|
||||
noteId: note.noteId,
|
||||
// title and text should be decrypted now
|
||||
title: note.title,
|
||||
contentLength: -1, // will be updated in .setContent()
|
||||
type: note.type,
|
||||
mime: note.mime,
|
||||
isProtected: false, // will be fixed in the protectNoteRevisions() call
|
||||
|
@ -466,7 +466,6 @@ function saveNoteRevision(note) {
|
||||
noteId: note.noteId,
|
||||
// title and text should be decrypted now
|
||||
title: note.title,
|
||||
contentLength: -1, // will be updated in .setContent()
|
||||
type: note.type,
|
||||
mime: note.mime,
|
||||
isProtected: false, // will be fixed in the protectNoteRevisions() call
|
||||
@ -699,7 +698,6 @@ function eraseDeletedNotes() {
|
||||
sql.executeMany(`
|
||||
UPDATE notes
|
||||
SET title = '[deleted]',
|
||||
contentLength = 0,
|
||||
isProtected = 0,
|
||||
isErased = 1
|
||||
WHERE noteId IN (???)`, noteIdsToErase);
|
||||
@ -719,8 +717,7 @@ function eraseDeletedNotes() {
|
||||
sql.executeMany(`
|
||||
UPDATE note_revisions
|
||||
SET isErased = 1,
|
||||
title = NULL,
|
||||
contentLength = 0
|
||||
title = NULL
|
||||
WHERE isErased = 0 AND noteId IN (???)`, noteIdsToErase);
|
||||
|
||||
sql.executeMany(`
|
||||
|
@ -18,7 +18,6 @@ const PROP_MAPPING = {
|
||||
"datemodified": "dateModified",
|
||||
"utcdatecreated": "utcDateCreated",
|
||||
"utcdatemodified": "utcDateModified",
|
||||
"contentlength": "contentLength",
|
||||
"parentcount": "parentCount",
|
||||
"childrencount": "childrenCount",
|
||||
"attributecount": "attributeCount",
|
||||
|
@ -15,7 +15,6 @@ const PROP_MAPPING = {
|
||||
"datemodified": "dateModified",
|
||||
"utcdatecreated": "utcDateCreated",
|
||||
"utcdatemodified": "utcDateModified",
|
||||
"contentlength": "contentLength",
|
||||
"parentcount": "parentCount",
|
||||
"childrencount": "childrenCount",
|
||||
"attributecount": "attributeCount",
|
||||
|
@ -93,9 +93,9 @@ function getValue(query, params = []) {
|
||||
return row[Object.keys(row)[0]];
|
||||
}
|
||||
|
||||
const PARAM_LIMIT = 900; // actual limit is 999
|
||||
// smaller values can result in better performance due to better usage of statement cache
|
||||
const PARAM_LIMIT = 100;
|
||||
|
||||
// this is to overcome 999 limit of number of query parameters
|
||||
function getManyRows(query, params) {
|
||||
let results = [];
|
||||
|
||||
@ -114,7 +114,11 @@ function getManyRows(query, params) {
|
||||
const questionMarks = curParams.map(() => ":param" + i++).join(",");
|
||||
const curQuery = query.replace(/\?\?\?/g, questionMarks);
|
||||
|
||||
const subResults = dbConnection.prepare(curQuery).all(curParamsObj);
|
||||
const statement = curParams.length === PARAM_LIMIT
|
||||
? stmt(curQuery)
|
||||
: dbConnection.prepare(curQuery);
|
||||
|
||||
const subResults = statement.all(curParamsObj);
|
||||
results = results.concat(subResults);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ function getNotes(noteIds) {
|
||||
SELECT
|
||||
noteId,
|
||||
title,
|
||||
contentLength,
|
||||
isProtected,
|
||||
type,
|
||||
mime,
|
||||
|
Loading…
x
Reference in New Issue
Block a user