mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 21:19:01 +01:00 
			
		
		
		
	share improvements/cleanup
This commit is contained in:
		
							parent
							
								
									94111c464b
								
							
						
					
					
						commit
						972f2f40bf
					
				@ -43,7 +43,7 @@ body {
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.type-image img {
 | 
			
		||||
img {
 | 
			
		||||
    max-width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @module sql
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: some methods (like getValue()) could use raw rows
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const log = require('./log');
 | 
			
		||||
@ -89,13 +91,7 @@ function getRowOrNull(query, params = []) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getValue(query, params = []) {
 | 
			
		||||
    const row = getRowOrNull(query, params);
 | 
			
		||||
 | 
			
		||||
    if (!row) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return row[Object.keys(row)[0]];
 | 
			
		||||
    return wrap(query, s => s.pluck().get(params));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// smaller values can result in better performance due to better usage of statement cache
 | 
			
		||||
@ -144,32 +140,17 @@ function iterateRows(query, params = []) {
 | 
			
		||||
 | 
			
		||||
function getMap(query, params = []) {
 | 
			
		||||
    const map = {};
 | 
			
		||||
    const results = getRows(query, params);
 | 
			
		||||
    const results = getRawRows(query, params);
 | 
			
		||||
 | 
			
		||||
    for (const row of results) {
 | 
			
		||||
        const keys = Object.keys(row);
 | 
			
		||||
 | 
			
		||||
        map[row[keys[0]]] = row[keys[1]];
 | 
			
		||||
        map[row[0]] = row[1];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return map;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getColumn(query, params = []) {
 | 
			
		||||
    const list = [];
 | 
			
		||||
    const result = getRows(query, params);
 | 
			
		||||
 | 
			
		||||
    if (result.length === 0) {
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const key = Object.keys(result[0])[0];
 | 
			
		||||
 | 
			
		||||
    for (const row of result) {
 | 
			
		||||
        list.push(row[key]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return list;
 | 
			
		||||
    return wrap(query, s => s.pluck().all(params));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function execute(query, params = []) {
 | 
			
		||||
 | 
			
		||||
@ -34,15 +34,28 @@ function load() {
 | 
			
		||||
 | 
			
		||||
    const noteIdStr = noteIds.map(noteId => `'${noteId}'`).join(",");
 | 
			
		||||
 | 
			
		||||
    for (const row of sql.getRawRows(`SELECT noteId, title, type, mime, utcDateModified FROM notes WHERE isDeleted = 0 AND noteId IN (${noteIdStr})`)) {
 | 
			
		||||
    const rawNoteRows = sql.getRawRows(`
 | 
			
		||||
        SELECT noteId, title, type, mime, utcDateModified 
 | 
			
		||||
        FROM notes 
 | 
			
		||||
        WHERE isDeleted = 0 
 | 
			
		||||
          AND noteId IN (${noteIdStr})`);
 | 
			
		||||
 | 
			
		||||
    for (const row of rawNoteRows) {
 | 
			
		||||
        new Note(row);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const row of sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0 AND parentNoteId IN (${noteIdStr}) ORDER BY notePosition`)) {
 | 
			
		||||
    const rawBranchRows = sql.getRawRows(`
 | 
			
		||||
        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 Branch(row);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const attributes = sql.getRawRows(`
 | 
			
		||||
    const rawAttributeRows = sql.getRawRows(`
 | 
			
		||||
        SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified 
 | 
			
		||||
        FROM attributes 
 | 
			
		||||
        WHERE isDeleted = 0 
 | 
			
		||||
@ -52,13 +65,13 @@ function load() {
 | 
			
		||||
              OR (type = 'relation' AND name IN ('imageLink', 'template', 'shareCss'))
 | 
			
		||||
          )`, []);
 | 
			
		||||
 | 
			
		||||
    for (const row of attributes) {
 | 
			
		||||
    for (const row of rawAttributeRows) {
 | 
			
		||||
        new Attribute(row);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    shaca.loaded = true;
 | 
			
		||||
 | 
			
		||||
    log.info(`Shaca load took ${Date.now() - start}ms`);
 | 
			
		||||
    log.info(`Shaca loaded ${rawNoteRows.length} notes, ${rawBranchRows.length} branches, ${rawAttributeRows.length} attributes took ${Date.now() - start}ms`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ensureLoad() {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										143
									
								
								src/share/sql.js
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								src/share/sql.js
									
									
									
									
									
								
							@ -1,6 +1,5 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
const log = require('../services/log');
 | 
			
		||||
const Database = require('better-sqlite3');
 | 
			
		||||
const dataDir = require('../services/data_dir');
 | 
			
		||||
 | 
			
		||||
@ -16,152 +15,20 @@ const dbConnection = new Database(dataDir.DOCUMENT_PATH, { readonly: true });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const statementCache = {};
 | 
			
		||||
 | 
			
		||||
function stmt(sql) {
 | 
			
		||||
    if (!(sql in statementCache)) {
 | 
			
		||||
        statementCache[sql] = dbConnection.prepare(sql);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return statementCache[sql];
 | 
			
		||||
function getRawRows(query, params = []) {
 | 
			
		||||
    return dbConnection.prepare(query).raw().all(params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getRow(query, params = []) {
 | 
			
		||||
    return wrap(query, s => s.get(params));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getRowOrNull(query, params = []) {
 | 
			
		||||
    const all = getRows(query, params);
 | 
			
		||||
 | 
			
		||||
    return all.length > 0 ? all[0] : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getValue(query, params = []) {
 | 
			
		||||
    const row = getRowOrNull(query, params);
 | 
			
		||||
 | 
			
		||||
    if (!row) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return row[Object.keys(row)[0]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// smaller values can result in better performance due to better usage of statement cache
 | 
			
		||||
const PARAM_LIMIT = 100;
 | 
			
		||||
 | 
			
		||||
function getManyRows(query, params) {
 | 
			
		||||
    let results = [];
 | 
			
		||||
 | 
			
		||||
    while (params.length > 0) {
 | 
			
		||||
        const curParams = params.slice(0, Math.min(params.length, PARAM_LIMIT));
 | 
			
		||||
        params = params.slice(curParams.length);
 | 
			
		||||
 | 
			
		||||
        const curParamsObj = {};
 | 
			
		||||
 | 
			
		||||
        let j = 1;
 | 
			
		||||
        for (const param of curParams) {
 | 
			
		||||
            curParamsObj['param' + j++] = param;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let i = 1;
 | 
			
		||||
        const questionMarks = curParams.map(() => ":param" + i++).join(",");
 | 
			
		||||
        const curQuery = query.replace(/\?\?\?/g, questionMarks);
 | 
			
		||||
 | 
			
		||||
        const statement = curParams.length === PARAM_LIMIT
 | 
			
		||||
            ? stmt(curQuery)
 | 
			
		||||
            : dbConnection.prepare(curQuery);
 | 
			
		||||
 | 
			
		||||
        const subResults = statement.all(curParamsObj);
 | 
			
		||||
        results = results.concat(subResults);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return results;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getRows(query, params = []) {
 | 
			
		||||
    return wrap(query, s => s.all(params));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getRawRows(query, params = []) {
 | 
			
		||||
    return wrap(query, s => s.raw().all(params));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function iterateRows(query, params = []) {
 | 
			
		||||
    return stmt(query).iterate(params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getMap(query, params = []) {
 | 
			
		||||
    const map = {};
 | 
			
		||||
    const results = getRows(query, params);
 | 
			
		||||
 | 
			
		||||
    for (const row of results) {
 | 
			
		||||
        const keys = Object.keys(row);
 | 
			
		||||
 | 
			
		||||
        map[row[keys[0]]] = row[keys[1]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return map;
 | 
			
		||||
    return dbConnection.prepare(query).get(params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getColumn(query, params = []) {
 | 
			
		||||
    const list = [];
 | 
			
		||||
    const result = getRows(query, params);
 | 
			
		||||
 | 
			
		||||
    if (result.length === 0) {
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const key = Object.keys(result[0])[0];
 | 
			
		||||
 | 
			
		||||
    for (const row of result) {
 | 
			
		||||
        list.push(row[key]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function wrap(query, func) {
 | 
			
		||||
    const startTimestamp = Date.now();
 | 
			
		||||
    let result;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
        result = func(stmt(query));
 | 
			
		||||
    }
 | 
			
		||||
    catch (e) {
 | 
			
		||||
        if (e.message.includes("The database connection is not open")) {
 | 
			
		||||
            // this often happens on killing the app which puts these alerts in front of user
 | 
			
		||||
            // in these cases error should be simply ignored.
 | 
			
		||||
            console.log(e.message);
 | 
			
		||||
 | 
			
		||||
            return null
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw e;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const milliseconds = Date.now() - startTimestamp;
 | 
			
		||||
 | 
			
		||||
    if (milliseconds >= 20) {
 | 
			
		||||
        if (query.includes("WITH RECURSIVE")) {
 | 
			
		||||
            log.info(`Slow recursive query took ${milliseconds}ms.`);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            log.info(`Slow query took ${milliseconds}ms: ${query.trim().replace(/\s+/g, " ")}`);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
    return dbConnection.prepare(query).pluck().all(params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
    dbConnection,
 | 
			
		||||
    getValue,
 | 
			
		||||
    getRow,
 | 
			
		||||
    getRowOrNull,
 | 
			
		||||
    getRows,
 | 
			
		||||
    getRawRows,
 | 
			
		||||
    iterateRows,
 | 
			
		||||
    getManyRows,
 | 
			
		||||
    getMap,
 | 
			
		||||
    getRow,
 | 
			
		||||
    getColumn
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user