Notes/src/share/shaca/shaca_loader.ts
2025-01-09 18:36:24 +02:00

105 lines
2.9 KiB
TypeScript

"use strict";
import sql from "../sql.js";
import shaca from "./shaca.js";
import log from "../../services/log.js";
import SNote from "./entities/snote.js";
import SBranch from "./entities/sbranch.js";
import SAttribute from "./entities/sattribute.js";
import SAttachment from "./entities/sattachment.js";
import shareRoot from "../share_root.js";
import eventService from "../../services/events.js";
import type { SAttachmentRow, SAttributeRow, SBranchRow, SNoteRow } from "./entities/rows.js";
function load() {
const start = Date.now();
shaca.reset();
// using a raw query and passing arrays to avoid allocating new objects
const noteIds = sql.getColumn(
`
WITH RECURSIVE
tree(noteId) AS (
SELECT ?
UNION
SELECT branches.noteId FROM branches
JOIN tree ON branches.parentNoteId = tree.noteId
WHERE branches.isDeleted = 0
)
SELECT noteId FROM tree`,
[shareRoot.SHARE_ROOT_NOTE_ID]
);
if (noteIds.length === 0) {
shaca.loaded = true;
return;
}
const noteIdStr = noteIds.map((noteId) => `'${noteId}'`).join(",");
const rawNoteRows = sql.getRawRows<SNoteRow>(`
SELECT noteId, title, type, mime, blobId, utcDateModified, isProtected
FROM notes
WHERE isDeleted = 0
AND noteId IN (${noteIdStr})`);
for (const row of rawNoteRows) {
new SNote(row);
}
const rawBranchRows = sql.getRawRows<SBranchRow>(`
SELECT branchId, noteId, parentNoteId, prefix, isExpanded, utcDateModified
FROM branches
WHERE isDeleted = 0
AND parentNoteId IN (${noteIdStr})
ORDER BY notePosition`);
for (const row of rawBranchRows) {
new SBranch(row);
}
const rawAttributeRows = sql.getRawRows<SAttributeRow>(`
SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified
FROM attributes
WHERE isDeleted = 0
AND noteId IN (${noteIdStr})`);
for (const row of rawAttributeRows) {
new SAttribute(row);
}
const rawAttachmentRows = sql.getRawRows<SAttachmentRow>(`
SELECT attachmentId, ownerId, role, mime, title, blobId, utcDateModified
FROM attachments
WHERE isDeleted = 0
AND ownerId IN (${noteIdStr})`);
for (const row of rawAttachmentRows) {
new SAttachment(row);
}
shaca.loaded = true;
log.info(`Shaca loaded ${rawNoteRows.length} notes, ${rawBranchRows.length} branches, ${rawAttachmentRows.length} attributes took ${Date.now() - start}ms`);
}
function ensureLoad() {
if (!shaca.loaded) {
load();
}
}
eventService.subscribe(
[eventService.ENTITY_CREATED, eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED, eventService.ENTITY_CHANGE_SYNCED, eventService.ENTITY_DELETE_SYNCED],
({ entityName, entity }) => {
shaca.reset();
}
);
export default {
load,
ensureLoad
};