Notes/src/routes/api/sql.ts
2025-01-09 18:36:24 +02:00

71 lines
1.8 KiB
TypeScript

"use strict";
import sql from "../../services/sql.js";
import becca from "../../becca/becca.js";
import type { Request } from "express";
import ValidationError from "../../errors/validation_error.js";
function getSchema() {
const tableNames = sql.getColumn(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
const tables = [];
for (const tableName of tableNames) {
tables.push({
name: tableName,
columns: sql.getRows(`PRAGMA table_info(${tableName})`)
});
}
return tables;
}
function execute(req: Request) {
const note = becca.getNoteOrThrow(req.params.noteId);
const content = note.getContent();
if (typeof content !== "string") {
throw new ValidationError("Invalid note type.");
}
const queries = content.split("\n---");
try {
const results = [];
for (let query of queries) {
query = query.trim();
while (query.startsWith("-- ")) {
// Query starts with one or more SQL comments, discard these before we execute.
const pivot = query.indexOf("\n");
query = pivot > 0 ? query.substr(pivot + 1).trim() : "";
}
if (!query) {
continue;
}
if (query.toLowerCase().startsWith("select") || query.toLowerCase().startsWith("with")) {
results.push(sql.getRows(query));
} else {
results.push(sql.execute(query));
}
}
return {
success: true,
results
};
} catch (e: any) {
return {
success: false,
error: e.message
};
}
}
export default {
getSchema,
execute
};