mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
order by note size + attachments + revisions, closes #4295
This commit is contained in:
parent
62ccf798ee
commit
1261a06a30
1
db/migrations/0226__rename_noteSize_label.sql
Normal file
1
db/migrations/0226__rename_noteSize_label.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
UPDATE attributes SET value = 'contentAndAttachmentsAndRevisionsSize' WHERE name = 'orderBy' AND value = 'noteSize';
|
@ -132,11 +132,17 @@ class BNote extends AbstractBeccaEntity {
|
|||||||
*/
|
*/
|
||||||
this.contentSize = null;
|
this.contentSize = null;
|
||||||
/**
|
/**
|
||||||
* size of the content and note revision contents in bytes
|
* size of the note content, attachment contents in bytes
|
||||||
* @type {int|null}
|
* @type {int|null}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.noteSize = null;
|
this.contentAndAttachmentsSize = null;
|
||||||
|
/**
|
||||||
|
* size of the note content, attachment contents and revision contents in bytes
|
||||||
|
* @type {int|null}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.contentAndAttachmentsAndRevisionsSize = null;
|
||||||
/**
|
/**
|
||||||
* number of note revisions for this note
|
* number of note revisions for this note
|
||||||
* @type {int|null}
|
* @type {int|null}
|
||||||
|
@ -127,7 +127,8 @@ paths:
|
|||||||
- targetRelationCount
|
- targetRelationCount
|
||||||
- targetRelationCountIncludingLinks
|
- targetRelationCountIncludingLinks
|
||||||
- contentSize
|
- contentSize
|
||||||
- noteSize
|
- contentAndAttachmentsSize
|
||||||
|
- contentAndAttachmentsAndRevisionsSize
|
||||||
- revisionCount
|
- revisionCount
|
||||||
- name: orderDirection
|
- name: orderDirection
|
||||||
in: query
|
in: query
|
||||||
|
@ -14,7 +14,8 @@ const TPL = `
|
|||||||
<option value="dateCreated">Date created</option>
|
<option value="dateCreated">Date created</option>
|
||||||
<option value="dateModified">Date of last modification</option>
|
<option value="dateModified">Date of last modification</option>
|
||||||
<option value="contentSize">Note content size</option>
|
<option value="contentSize">Note content size</option>
|
||||||
<option value="noteSize">Note content size including revisions</option>
|
<option value="contentAndAttachmentsSize">Note content size including attachments</option>
|
||||||
|
<option value="contentAndAttachmentsAndRevisionsSize">Note content size including attachments and revisions</option>
|
||||||
<option value="revisionCount">Number of revisions</option>
|
<option value="revisionCount">Number of revisions</option>
|
||||||
<option value="childrenCount">Number of children notes</option>
|
<option value="childrenCount">Number of children notes</option>
|
||||||
<option value="parentCount">Number of clones</option>
|
<option value="parentCount">Number of clones</option>
|
||||||
|
@ -4,7 +4,7 @@ const build = require('./build');
|
|||||||
const packageJson = require('../../package');
|
const packageJson = require('../../package');
|
||||||
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
const {TRILIUM_DATA_DIR} = require('./data_dir');
|
||||||
|
|
||||||
const APP_DB_VERSION = 225;
|
const APP_DB_VERSION = 226;
|
||||||
const SYNC_VERSION = 31;
|
const SYNC_VERSION = 31;
|
||||||
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
const CLIPPER_PROTOCOL_VERSION = "1.0";
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ class OrderByAndLimitExp extends Expression {
|
|||||||
if (!valA && !valB) {
|
if (!valA && !valB) {
|
||||||
// the attribute value is empty/zero in both notes so continue to the next order definition
|
// the attribute value is empty/zero in both notes so continue to the next order definition
|
||||||
continue;
|
continue;
|
||||||
} else if (!valB || valA < valB) {
|
} else if (valA < valB) {
|
||||||
return smaller;
|
return smaller;
|
||||||
} else if (!valA || valA > valB) {
|
} else if (valA > valB) {
|
||||||
return larger;
|
return larger;
|
||||||
}
|
}
|
||||||
// else the values are equal and continue to next order definition
|
// else the values are equal and continue to next order definition
|
||||||
|
@ -31,7 +31,8 @@ const PROP_MAPPING = {
|
|||||||
"targetrelationcount": "targetRelationCount",
|
"targetrelationcount": "targetRelationCount",
|
||||||
"targetrelationcountincludinglinks": "targetRelationCountIncludingLinks",
|
"targetrelationcountincludinglinks": "targetRelationCountIncludingLinks",
|
||||||
"contentsize": "contentSize",
|
"contentsize": "contentSize",
|
||||||
"notesize": "noteSize",
|
"contentandattachmentssize": "contentAndAttachmentsSize",
|
||||||
|
"contentandattachmentsandrevisionssize": "contentAndAttachmentsAndRevisionsSize",
|
||||||
"revisioncount": "revisionCount"
|
"revisioncount": "revisionCount"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ class PropertyComparisonExp extends Expression {
|
|||||||
this.comparedValue = comparedValue; // for DEBUG mode
|
this.comparedValue = comparedValue; // for DEBUG mode
|
||||||
this.comparator = buildComparator(operator, comparedValue);
|
this.comparator = buildComparator(operator, comparedValue);
|
||||||
|
|
||||||
if (['contentsize', 'notesize', 'revisioncount'].includes(this.propertyName)) {
|
if (['contentsize', 'contentandattachmentssize', 'contentandattachmentsandrevisionssize', 'revisioncount'].includes(this.propertyName)) {
|
||||||
searchContext.dbLoadNeeded = true;
|
searchContext.dbLoadNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,48 +92,87 @@ function searchFromRelation(note, relationName) {
|
|||||||
function loadNeededInfoFromDatabase() {
|
function loadNeededInfoFromDatabase() {
|
||||||
const sql = require('../../sql');
|
const sql = require('../../sql');
|
||||||
|
|
||||||
for (const noteId in becca.notes) {
|
const noteBlobs = {};
|
||||||
becca.notes[noteId].contentSize = 0;
|
|
||||||
becca.notes[noteId].noteSize = 0;
|
|
||||||
becca.notes[noteId].revisionCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const noteContentLengths = sql.getRows(`
|
const noteContentLengths = sql.getRows(`
|
||||||
SELECT
|
SELECT
|
||||||
noteId,
|
noteId,
|
||||||
|
blobId,
|
||||||
LENGTH(content) AS length
|
LENGTH(content) AS length
|
||||||
FROM notes
|
FROM notes
|
||||||
JOIN blobs USING(blobId)
|
JOIN blobs USING(blobId)
|
||||||
WHERE notes.isDeleted = 0`);
|
WHERE notes.isDeleted = 0`);
|
||||||
|
|
||||||
for (const {noteId, length} of noteContentLengths) {
|
for (const {noteId, blobId, length} of noteContentLengths) {
|
||||||
if (!(noteId in becca.notes)) {
|
if (!(noteId in becca.notes)) {
|
||||||
log.error(`Note ${noteId} not found in becca.`);
|
log.error(`Note '${noteId}' not found in becca.`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
becca.notes[noteId].contentSize = length;
|
becca.notes[noteId].contentSize = length;
|
||||||
becca.notes[noteId].noteSize = length;
|
becca.notes[noteId].revisionCount = 0;
|
||||||
|
|
||||||
|
noteBlobs[noteId] = { [blobId]: length };
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachmentContentLengths = sql.getRows(`
|
||||||
|
SELECT
|
||||||
|
ownerId AS noteId,
|
||||||
|
attachments.blobId,
|
||||||
|
LENGTH(content) AS length
|
||||||
|
FROM attachments
|
||||||
|
JOIN notes ON attachments.ownerId = notes.noteId
|
||||||
|
JOIN blobs ON attachments.blobId = blobs.blobId
|
||||||
|
WHERE attachments.isDeleted = 0
|
||||||
|
AND notes.isDeleted = 0`);
|
||||||
|
|
||||||
|
for (const {noteId, blobId, length} of attachmentContentLengths) {
|
||||||
|
if (!(noteId in becca.notes)) {
|
||||||
|
log.error(`Note '${noteId}' not found in becca.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(noteId in noteBlobs)) {
|
||||||
|
log.error(`Did not find a '${noteId}' in the noteBlobs.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
noteBlobs[noteId][blobId] = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const noteId in noteBlobs) {
|
||||||
|
becca.notes[noteId].contentAndAttachmentsSize = Object.values(noteBlobs[noteId]).reduce((acc, size) => acc + size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const revisionContentLengths = sql.getRows(`
|
const revisionContentLengths = sql.getRows(`
|
||||||
SELECT
|
SELECT
|
||||||
noteId,
|
noteId,
|
||||||
|
revisions.blobId,
|
||||||
LENGTH(content) AS length
|
LENGTH(content) AS length
|
||||||
FROM notes
|
FROM notes
|
||||||
JOIN revisions USING(noteId)
|
JOIN revisions USING(noteId)
|
||||||
JOIN blobs USING(blobId)
|
JOIN blobs ON revisions.blobId = blobs.blobId
|
||||||
WHERE notes.isDeleted = 0`);
|
WHERE notes.isDeleted = 0`);
|
||||||
|
|
||||||
for (const {noteId, length} of revisionContentLengths) {
|
for (const {noteId, blobId, length} of revisionContentLengths) {
|
||||||
if (!(noteId in becca.notes)) {
|
if (!(noteId in becca.notes)) {
|
||||||
log.error(`Note ${noteId} not found in becca.`);
|
log.error(`Note '${noteId}' not found in becca.`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
becca.notes[noteId].noteSize += length;
|
if (!(noteId in noteBlobs)) {
|
||||||
|
log.error(`Did not find a '${noteId}' in the noteBlobs.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
noteBlobs[noteId][blobId] = length;
|
||||||
|
|
||||||
becca.notes[noteId].revisionCount++;
|
becca.notes[noteId].revisionCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const noteId in noteBlobs) {
|
||||||
|
becca.notes[noteId].contentAndAttachmentsAndRevisionsSize = Object.values(noteBlobs[noteId]).reduce((acc, size) => acc + size, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,8 @@ const PROP_MAPPING = {
|
|||||||
"targetrelationcount": "targetRelationCount",
|
"targetrelationcount": "targetRelationCount",
|
||||||
"targetrelationcountincludinglinks": "targetRelationCountIncludingLinks",
|
"targetrelationcountincludinglinks": "targetRelationCountIncludingLinks",
|
||||||
"contentsize": "contentSize",
|
"contentsize": "contentSize",
|
||||||
"notesize": "noteSize",
|
"contentandattachmentssize": "contentAndAttachmentsSize",
|
||||||
|
"contentandattachmentsandrevisionssize": "contentAndAttachmentsAndRevisionsSize",
|
||||||
"revisioncount": "revisionCount"
|
"revisioncount": "revisionCount"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class ValueExtractor {
|
|||||||
this.propertyPath = ['note', 'relations', this.propertyPath[0].substr(1), ...this.propertyPath.slice(1, this.propertyPath.length)];
|
this.propertyPath = ['note', 'relations', this.propertyPath[0].substr(1), ...this.propertyPath.slice(1, this.propertyPath.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['contentsize', 'notesize', 'revisioncount'].includes(this.propertyPath[this.propertyPath.length - 1])) {
|
if (['contentsize', 'contentandattachmentssize', 'contentandattachmentsandrevisionssize', 'revisioncount'].includes(this.propertyPath[this.propertyPath.length - 1])) {
|
||||||
searchContext.dbLoadNeeded = true;
|
searchContext.dbLoadNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user