mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
becca conversion WIP
This commit is contained in:
parent
77eac8f764
commit
273d4e0052
@ -3,7 +3,7 @@ const Note = require('../entities/note');
|
||||
const NoteRevision = require('../services/becca/entities/note_revision.js');
|
||||
const Branch = require('../entities/branch');
|
||||
const Attribute = require('../entities/attribute');
|
||||
const RecentNote = require('../entities/recent_note');
|
||||
const RecentNote = require('../services/becca/entities/recent_note.js');
|
||||
const ApiToken = require('../entities/api_token');
|
||||
const cls = require('../services/cls');
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const Entity = require('./entity');
|
||||
const dateUtils = require('../services/date_utils');
|
||||
|
||||
/**
|
||||
* RecentNote represents recently visited note.
|
||||
*
|
||||
* @property {string} noteId
|
||||
* @property {string} notePath
|
||||
* @property {string} utcDateCreated
|
||||
*
|
||||
* @extends Entity
|
||||
*/
|
||||
class RecentNote extends Entity {
|
||||
static get entityName() { return "recent_notes"; }
|
||||
static get primaryKeyName() { return "noteId"; }
|
||||
|
||||
beforeSaving() {
|
||||
if (!this.utcDateCreated) {
|
||||
this.utcDateCreated = dateUtils.utcNowDateTime();
|
||||
}
|
||||
|
||||
super.beforeSaving();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RecentNote;
|
@ -5,7 +5,7 @@ const log = require('../../services/log');
|
||||
const attributeService = require('../../services/attributes');
|
||||
const repository = require('../../services/repository');
|
||||
const Attribute = require('../../entities/attribute');
|
||||
const becca = require("../../services/becca/becca.js");
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
function getEffectiveNoteAttributes(req) {
|
||||
const note = becca.getNote(req.params.noteId);
|
||||
|
@ -6,6 +6,7 @@ const repository = require('../../services/repository');
|
||||
const log = require('../../services/log');
|
||||
const utils = require('../../services/utils');
|
||||
const cls = require('../../services/cls');
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
function getAutocomplete(req) {
|
||||
const query = req.query.query.trim();
|
||||
@ -41,7 +42,7 @@ function getRecentNotes(activeNoteId) {
|
||||
params.push('%' + hoistedNoteId + '%');
|
||||
}
|
||||
|
||||
const recentNotes = repository.getEntities(`
|
||||
const recentNotes = becca.getRecentNotesFromQuery(`
|
||||
SELECT
|
||||
recent_notes.*
|
||||
FROM
|
||||
|
@ -9,7 +9,7 @@ const fs = require('fs');
|
||||
const { Readable } = require('stream');
|
||||
const chokidar = require('chokidar');
|
||||
const ws = require('../../services/ws');
|
||||
const becca = require("../../services/becca/becca.js");
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
function updateFile(req) {
|
||||
const {noteId} = req.params;
|
||||
|
@ -7,10 +7,10 @@ const noteRevisionService = require('../../services/note_revisions');
|
||||
const utils = require('../../services/utils');
|
||||
const sql = require('../../services/sql');
|
||||
const path = require('path');
|
||||
const becca = require("../../services/becca/becca.js");
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
function getNoteRevisions(req) {
|
||||
return repository.getEntities(`
|
||||
return becca.getNoteRevisionsFromQuery(`
|
||||
SELECT note_revisions.*,
|
||||
LENGTH(note_revision_contents.content) AS contentLength
|
||||
FROM note_revisions
|
||||
@ -107,7 +107,7 @@ function restoreNoteRevision(req) {
|
||||
}
|
||||
|
||||
function getEditedNotesOnDate(req) {
|
||||
const notes = repository.getEntities(`
|
||||
const noteIds = sql.getColumn(`
|
||||
SELECT notes.*
|
||||
FROM notes
|
||||
WHERE noteId IN (
|
||||
@ -121,6 +121,8 @@ function getEditedNotesOnDate(req) {
|
||||
ORDER BY isDeleted
|
||||
LIMIT 50`, {date: req.params.date + '%'});
|
||||
|
||||
const notes = becca.getNotes(noteIds);
|
||||
|
||||
for (const note of notes) {
|
||||
const notePath = note.isDeleted ? null : beccaService.getNotePath(note.noteId);
|
||||
|
||||
|
@ -9,7 +9,7 @@ const log = require('../../services/log');
|
||||
const TaskContext = require('../../services/task_context');
|
||||
const fs = require('fs');
|
||||
const noteRevisionService = require("../../services/note_revisions.js");
|
||||
const becca = require("../../services/becca/becca.js");
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
function getNote(req) {
|
||||
const noteId = req.params.noteId;
|
||||
@ -159,7 +159,8 @@ function getRelationMap(req) {
|
||||
|
||||
console.log("displayRelations", displayRelations);
|
||||
|
||||
const notes = repository.getEntities(`SELECT * FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds);
|
||||
const foundNoteIds = sql.getColumn(`SELECT noteId FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds);
|
||||
const notes = becca.getNotes(foundNoteIds);
|
||||
|
||||
for (const note of notes) {
|
||||
resp.noteTitles[note.noteId] = note.title;
|
||||
|
@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
const RecentNote = require('../../entities/recent_note');
|
||||
const RecentNote = require('../../services/becca/entities/recent_note.js');
|
||||
const sql = require('../../services/sql');
|
||||
const dateUtils = require('../../services/date_utils');
|
||||
|
||||
|
@ -6,6 +6,7 @@ const log = require('../../services/log');
|
||||
const scriptService = require('../../services/script');
|
||||
const searchService = require('../../services/search/services/search');
|
||||
const noteRevisionService = require("../../services/note_revisions.js");
|
||||
const {formatAttrForSearch} = require("../../services/attribute_formatter.js");
|
||||
|
||||
async function searchFromNoteInt(note) {
|
||||
let searchResultNoteIds;
|
||||
@ -267,51 +268,6 @@ function getRelatedNotes(req) {
|
||||
};
|
||||
}
|
||||
|
||||
function formatAttrForSearch(attr, searchWithValue) {
|
||||
let searchStr = '';
|
||||
|
||||
if (attr.type === 'label') {
|
||||
searchStr += '#';
|
||||
}
|
||||
else if (attr.type === 'relation') {
|
||||
searchStr += '~';
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized attribute type ${JSON.stringify(attr)}`);
|
||||
}
|
||||
|
||||
searchStr += attr.name;
|
||||
|
||||
if (searchWithValue && attr.value) {
|
||||
if (attr.type === 'relation') {
|
||||
searchStr += ".noteId";
|
||||
}
|
||||
|
||||
searchStr += '=';
|
||||
searchStr += formatValue(attr.value);
|
||||
}
|
||||
|
||||
return searchStr;
|
||||
}
|
||||
|
||||
function formatValue(val) {
|
||||
if (!/[^\w_-]/.test(val)) {
|
||||
return val;
|
||||
}
|
||||
else if (!val.includes('"')) {
|
||||
return '"' + val + '"';
|
||||
}
|
||||
else if (!val.includes("'")) {
|
||||
return "'" + val + "'";
|
||||
}
|
||||
else if (!val.includes("`")) {
|
||||
return "`" + val + "`";
|
||||
}
|
||||
else {
|
||||
return '"' + val.replace(/"/g, '\\"') + '"';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
searchFromNote,
|
||||
searchAndExecute,
|
||||
|
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const similarityService = require('../../services/becca/similarity.js');
|
||||
const becca = require("../../services/becca/becca.js");
|
||||
const becca = require("../../services/becca/becca");
|
||||
|
||||
async function getSimilarNotes(req) {
|
||||
const noteId = req.params.noteId;
|
||||
|
@ -3,13 +3,17 @@ const log = require('../services/log');
|
||||
const fileUploadService = require('./api/files.js');
|
||||
const scriptService = require('../services/script');
|
||||
const cls = require('../services/cls');
|
||||
const sql = require("../services/sql");
|
||||
const becca = require("../services/becca/becca");
|
||||
|
||||
async function handleRequest(req, res) {
|
||||
// express puts content after first slash into 0 index element
|
||||
|
||||
const path = req.params.path + req.params[0];
|
||||
|
||||
const attrs = repository.getEntities("SELECT * FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')");
|
||||
const attributeIds = sql.getColumn("SELECT attributeId FROM attributes WHERE isDeleted = 0 AND type = 'label' AND name IN ('customRequestHandler', 'customResourceProvider')");
|
||||
|
||||
const attrs = attributeIds.map(attrId => becca.getAttribute(attrId));
|
||||
|
||||
for (const attr of attrs) {
|
||||
if (!attr.value.trim()) {
|
||||
|
50
src/services/attribute_formatter.js
Normal file
50
src/services/attribute_formatter.js
Normal file
@ -0,0 +1,50 @@
|
||||
"use strict"
|
||||
|
||||
function formatAttrForSearch(attr, searchWithValue) {
|
||||
let searchStr = '';
|
||||
|
||||
if (attr.type === 'label') {
|
||||
searchStr += '#';
|
||||
}
|
||||
else if (attr.type === 'relation') {
|
||||
searchStr += '~';
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unrecognized attribute type ${JSON.stringify(attr)}`);
|
||||
}
|
||||
|
||||
searchStr += attr.name;
|
||||
|
||||
if (searchWithValue && attr.value) {
|
||||
if (attr.type === 'relation') {
|
||||
searchStr += ".noteId";
|
||||
}
|
||||
|
||||
searchStr += '=';
|
||||
searchStr += formatValue(attr.value);
|
||||
}
|
||||
|
||||
return searchStr;
|
||||
}
|
||||
|
||||
function formatValue(val) {
|
||||
if (!/[^\w_-]/.test(val)) {
|
||||
return val;
|
||||
}
|
||||
else if (!val.includes('"')) {
|
||||
return '"' + val + '"';
|
||||
}
|
||||
else if (!val.includes("'")) {
|
||||
return "'" + val + "'";
|
||||
}
|
||||
else if (!val.includes("`")) {
|
||||
return "`" + val + "`";
|
||||
}
|
||||
else {
|
||||
return '"' + val.replace(/"/g, '\\"') + '"';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatAttrForSearch
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
const repository = require('./repository');
|
||||
const searchService = require('./search/services/search');
|
||||
const sql = require('./sql');
|
||||
const becca = require('./becca/becca.js');
|
||||
const Attribute = require('../entities/attribute');
|
||||
const {formatAttrForSearch} = require("./attribute_formatter.js");
|
||||
|
||||
const ATTRIBUTE_TYPES = [ 'label', 'relation' ];
|
||||
|
||||
@ -59,16 +60,7 @@ const BUILTIN_ATTRIBUTES = [
|
||||
];
|
||||
|
||||
function getNotesWithLabel(name, value) {
|
||||
let valueCondition = "";
|
||||
let params = [name];
|
||||
|
||||
if (value !== undefined) {
|
||||
valueCondition = " AND attributes.value = ?";
|
||||
params.push(value);
|
||||
}
|
||||
|
||||
return repository.getEntities(`SELECT notes.* FROM notes JOIN attributes USING(noteId)
|
||||
WHERE notes.isDeleted = 0 AND attributes.isDeleted = 0 AND attributes.name = ? ${valueCondition} ORDER BY position`, params);
|
||||
return searchService.findNotes(formatAttrForSearch({type: 'label', name, value}, true));
|
||||
}
|
||||
|
||||
function getNoteIdsWithLabels(names) {
|
||||
|
@ -14,7 +14,7 @@ const cloningService = require('./cloning');
|
||||
const appInfo = require('./app_info');
|
||||
const searchService = require('./search/services/search');
|
||||
const SearchContext = require("./search/search_context.js");
|
||||
const becca = require("./becca/becca.js");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
/**
|
||||
* This is the main backend API interface for scripts. It's published in the local "api" object.
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const sql = require("../sql.js");
|
||||
const NoteRevision = require("./entities/note_revision.js");
|
||||
const RecentNote = require("./entities/recent_note.js");
|
||||
|
||||
class Becca {
|
||||
constructor() {
|
||||
@ -94,6 +95,18 @@ class Becca {
|
||||
|
||||
return this[camelCaseEntityName][entityId];
|
||||
}
|
||||
|
||||
getRecentNotesFromQuery(query, params = []) {
|
||||
const rows = sql.getRows(query, params);
|
||||
|
||||
return rows.map(row => new RecentNote(row));
|
||||
}
|
||||
|
||||
getNoteRevisionsFromQuery(query, params = []) {
|
||||
const rows = sql.getRows(query, params);
|
||||
|
||||
return rows.map(row => new NoteRevision(row));
|
||||
}
|
||||
}
|
||||
|
||||
const becca = new Becca();
|
||||
|
22
src/services/becca/entities/recent_note.js
Normal file
22
src/services/becca/entities/recent_note.js
Normal file
@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
const dateUtils = require('../../date_utils.js');
|
||||
const AbstractEntity = require("./abstract_entity.js");
|
||||
|
||||
/**
|
||||
* RecentNote represents recently visited note.
|
||||
*/
|
||||
class RecentNote extends AbstractEntity {
|
||||
static get entityName() { return "recent_notes"; }
|
||||
static get primaryKeyName() { return "noteId"; }
|
||||
|
||||
constructor(row) {
|
||||
super();
|
||||
|
||||
this.noteId = row.noteId;
|
||||
this.notePath = row.notePath;
|
||||
this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RecentNote;
|
@ -8,7 +8,7 @@ const repository = require('./repository');
|
||||
const Branch = require('../entities/branch');
|
||||
const TaskContext = require("./task_context.js");
|
||||
const utils = require('./utils');
|
||||
const becca = require("./becca/becca.js");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
function cloneNoteToParent(noteId, parentBranchId, prefix) {
|
||||
const parentBranch = becca.getBranch(parentBranchId);
|
||||
|
@ -13,7 +13,7 @@ const Branch = require('../entities/branch');
|
||||
const dateUtils = require('./date_utils');
|
||||
const attributeService = require('./attributes');
|
||||
const noteRevisionService = require('./note_revisions');
|
||||
const becca = require("./becca/becca.js");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
class ConsistencyChecks {
|
||||
constructor(autoFix) {
|
||||
@ -244,13 +244,15 @@ class ConsistencyChecks {
|
||||
HAVING COUNT(1) > 1`,
|
||||
({noteId, parentNoteId}) => {
|
||||
if (this.autoFix) {
|
||||
const branches = repository.getEntities(
|
||||
`SELECT *
|
||||
const branchIds = sql.getColumn(
|
||||
`SELECT branchId
|
||||
FROM branches
|
||||
WHERE noteId = ?
|
||||
and parentNoteId = ?
|
||||
and isDeleted = 0`, [noteId, parentNoteId]);
|
||||
|
||||
const branches = branchIds.map(branchId => becca.getBranch(branchId));
|
||||
|
||||
// it's not necessarily "original" branch, it's just the only one which will survive
|
||||
const origBranch = branches[0];
|
||||
|
||||
@ -359,11 +361,13 @@ class ConsistencyChecks {
|
||||
AND branches.isDeleted = 0`,
|
||||
({parentNoteId}) => {
|
||||
if (this.autoFix) {
|
||||
const branches = repository.getEntities(`SELECT *
|
||||
const branchIds = sql.getColumn(`SELECT branchId
|
||||
FROM branches
|
||||
WHERE isDeleted = 0
|
||||
AND parentNoteId = ?`, [parentNoteId]);
|
||||
|
||||
const branches = branchIds.map(branchId => becca.getBranch(branchId));
|
||||
|
||||
for (const branch of branches) {
|
||||
branch.parentNoteId = 'root';
|
||||
branch.save();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const repository = require("../repository");
|
||||
const utils = require('../utils');
|
||||
const becca = require("../becca/becca.js");
|
||||
const becca = require("../becca/becca");
|
||||
|
||||
function exportToOpml(taskContext, branch, version, res) {
|
||||
if (!['1.0', '2.0'].includes(version)) {
|
||||
|
@ -6,11 +6,8 @@ const entityChangesService = require('./entity_changes.js');
|
||||
const eventService = require('./events');
|
||||
const repository = require('./repository');
|
||||
const cls = require('../services/cls');
|
||||
const Note = require('../entities/note');
|
||||
const BeccaNote = require('../services/becca/entities/note.js');
|
||||
const Branch = require('../entities/branch');
|
||||
const BeccaBranch = require('../services/becca/entities/branch.js');
|
||||
const Attribute = require('../entities/attribute');
|
||||
const BeccaAttribute = require('../services/becca/entities/attribute.js');
|
||||
const protectedSessionService = require('../services/protected_session');
|
||||
const log = require('../services/log');
|
||||
@ -617,14 +614,14 @@ function undeleteBranch(branch, deleteId, taskContext) {
|
||||
note.isDeleted = false;
|
||||
note.save();
|
||||
|
||||
const attrs = repository.getEntities(`
|
||||
SELECT * FROM attributes
|
||||
const attributeIds = sql.getColumn(`
|
||||
SELECT attributeId FROM attributes
|
||||
WHERE isDeleted = 1
|
||||
AND deleteId = ?
|
||||
AND (noteId = ?
|
||||
OR (type = 'relation' AND value = ?))`, [deleteId, note.noteId, note.noteId]);
|
||||
|
||||
for (const attr of attrs) {
|
||||
for (const attr of attributeIds) {
|
||||
attr.isDeleted = false;
|
||||
attr.save();
|
||||
}
|
||||
@ -646,14 +643,16 @@ function undeleteBranch(branch, deleteId, taskContext) {
|
||||
* @return return deleted branches of an undeleted parent note
|
||||
*/
|
||||
function getUndeletedParentBranches(noteId, deleteId) {
|
||||
return repository.getEntities(`
|
||||
SELECT branches.*
|
||||
const branchIds = sql.getColumn(`
|
||||
SELECT branches.branchId
|
||||
FROM branches
|
||||
JOIN notes AS parentNote ON parentNote.noteId = branches.parentNoteId
|
||||
WHERE branches.noteId = ?
|
||||
AND branches.isDeleted = 1
|
||||
AND branches.deleteId = ?
|
||||
AND parentNote.isDeleted = 0`, [noteId, deleteId]);
|
||||
|
||||
return branchIds.map(branchId => becca.getBranch(branchId));
|
||||
}
|
||||
|
||||
function scanForLinks(note) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
const scriptService = require('./script');
|
||||
const repository = require('./repository');
|
||||
const cls = require('./cls');
|
||||
const sqlInit = require('./sql_init');
|
||||
const config = require('./config');
|
||||
const log = require('./log');
|
||||
const sql = require("./sql");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
function getRunAtHours(note) {
|
||||
try {
|
||||
@ -17,8 +18,9 @@ function getRunAtHours(note) {
|
||||
}
|
||||
|
||||
function runNotesWithLabel(runAttrValue) {
|
||||
const notes = repository.getEntities(`
|
||||
SELECT notes.*
|
||||
// TODO: should be refactored into becca search
|
||||
const noteIds = sql.getColumn(`
|
||||
SELECT notes.noteId
|
||||
FROM notes
|
||||
JOIN attributes ON attributes.noteId = notes.noteId
|
||||
AND attributes.isDeleted = 0
|
||||
@ -29,6 +31,8 @@ function runNotesWithLabel(runAttrValue) {
|
||||
notes.type = 'code'
|
||||
AND notes.isDeleted = 0`, [runAttrValue]);
|
||||
|
||||
const notes = becca.getNotes(noteIds);
|
||||
|
||||
const instanceName = config.General ? config.General.instanceName : null;
|
||||
const currentHours = new Date().getHours();
|
||||
|
||||
|
@ -2,7 +2,7 @@ const ScriptContext = require('./script_context');
|
||||
const repository = require('./repository');
|
||||
const cls = require('./cls');
|
||||
const log = require('./log');
|
||||
const becca = require("./becca/becca.js");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
async function executeNote(note, apiParams) {
|
||||
if (!note.isJavaScript() || note.getScriptEnv() !== 'backend' || !note.isContentAvailable) {
|
||||
|
@ -7,7 +7,7 @@ const syncOptions = require('./sync_options');
|
||||
const request = require('./request');
|
||||
const appInfo = require('./app_info');
|
||||
const utils = require('./utils');
|
||||
const becca = require("./becca/becca.js");
|
||||
const becca = require("./becca/becca");
|
||||
|
||||
async function hasSyncServerSchemaAndSeed() {
|
||||
const response = await requestToSyncServer('GET', '/api/setup/status');
|
||||
|
Loading…
x
Reference in New Issue
Block a user