share improvements/cleanup

This commit is contained in:
zadam 2021-12-23 12:54:21 +01:00
parent 94111c464b
commit 972f2f40bf
4 changed files with 30 additions and 169 deletions

View file

@ -43,7 +43,7 @@ body {
padding: 20px;
}
.type-image img {
img {
max-width: 100%;
}

View file

@ -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 = []) {

View file

@ -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() {

View file

@ -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
};