mirror of
https://github.com/stfrigerio/sqliteDB.git
synced 2026-07-22 05:38:02 +00:00
added codeblock "sql" to query the db
This commit is contained in:
parent
3706531e70
commit
62bfe308c6
3 changed files with 119 additions and 12 deletions
23
main.ts
23
main.ts
|
|
@ -8,10 +8,12 @@ import {
|
|||
FileSystemAdapter,
|
||||
Editor,
|
||||
MarkdownView,
|
||||
MarkdownPostProcessorContext
|
||||
} from "obsidian";
|
||||
|
||||
import { DBService } from "./src/dbService";
|
||||
import { inspectTableStructure, convertEntriesInNotes } from "./src/commands";
|
||||
import { pickTableName } from "./src/helpers";
|
||||
import { pickTableName, processSqlBlock } from "./src/helpers";
|
||||
import { SqliteDBSettings, DEFAULT_SETTINGS } from "./src/types";
|
||||
|
||||
export default class SqliteDBPlugin extends Plugin {
|
||||
|
|
@ -24,14 +26,7 @@ export default class SqliteDBPlugin extends Plugin {
|
|||
|
||||
this.dbService = new DBService();
|
||||
|
||||
//! i dont think we need this since we do it in each command
|
||||
// this.addCommand({
|
||||
// id: "open-db",
|
||||
// name: "Open Local SQLite DB",
|
||||
// callback: async () => {
|
||||
// await this.openDatabase();
|
||||
// },
|
||||
// });
|
||||
await this.openDatabase();
|
||||
|
||||
this.addCommand({
|
||||
id: "inspect-table-structure",
|
||||
|
|
@ -45,7 +40,7 @@ export default class SqliteDBPlugin extends Plugin {
|
|||
|
||||
this.addCommand({
|
||||
id: "dump-table-to-notes",
|
||||
name: "Dump Table Rows to Notes",
|
||||
name: "Dump Table to Notes",
|
||||
callback: async () => {
|
||||
await this.openDatabase(); // ensure DB is loaded
|
||||
|
||||
|
|
@ -59,7 +54,13 @@ export default class SqliteDBPlugin extends Plugin {
|
|||
await convertEntriesInNotes(this.dbService, chosenTable, this.app);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
this.registerMarkdownCodeBlockProcessor(
|
||||
"sql", // <-- the name of your code block (```sql)
|
||||
async (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
|
||||
await processSqlBlock(this.dbService, source, el);
|
||||
}
|
||||
);
|
||||
|
||||
this.addSettingTab(new SqliteDBSettingTab(this.app, this));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { pickTableName } from "./pickTableName";
|
||||
import { processSqlBlock } from "./processSqlBlock";
|
||||
|
||||
export { pickTableName };
|
||||
export { pickTableName, processSqlBlock };
|
||||
|
|
|
|||
105
src/helpers/processSqlBlock.ts
Normal file
105
src/helpers/processSqlBlock.ts
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import { Notice } from "obsidian";
|
||||
import { DBService } from "../dbService";
|
||||
|
||||
/**
|
||||
* Processes a code block of the form:
|
||||
*
|
||||
* ```sqlite
|
||||
* table: MyTable
|
||||
* keyColumn: id
|
||||
* value: 5
|
||||
* columns: col1, col2, col3
|
||||
* ```
|
||||
*
|
||||
* - If `columns` is specified, we only select those columns.
|
||||
* - Otherwise, we select all columns (*).
|
||||
* - If multiple rows match, we create one table per row.
|
||||
*/
|
||||
export async function processSqlBlock(dbService: DBService, source: string, el: HTMLElement) {
|
||||
const db = dbService.getDB();
|
||||
if (!db) {
|
||||
new Notice("No DB loaded. Please open the DB first.");
|
||||
el.createEl("p", { text: "Database not loaded." });
|
||||
return;
|
||||
}
|
||||
|
||||
// 1) Parse code block params
|
||||
const params = parseSqlParams(source);
|
||||
const { table, keyColumn, value, columns } = params;
|
||||
|
||||
if (!table || !keyColumn || !value) {
|
||||
el.createEl("p", { text: "Missing required parameters (table, keyColumn, value)." });
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Build query based on columns
|
||||
// If columns was provided, we split on commas, else use "*".
|
||||
let selectCols = "*";
|
||||
if (columns) {
|
||||
// e.g. "col1, col2" => "col1, col2"
|
||||
const colList = columns.split(",").map((c) => c.trim()).join(", ");
|
||||
selectCols = colList;
|
||||
}
|
||||
|
||||
const query = `SELECT ${selectCols} FROM "${table}" WHERE "${keyColumn}" = ?;`;
|
||||
const result = db.exec(query, [value]);
|
||||
|
||||
if (!result || result.length === 0 || result[0].values.length === 0) {
|
||||
el.createEl("p", {
|
||||
text: `No rows found in ${table} where ${keyColumn} = ${value}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// result[0] => { columns: string[], values: any[][] }
|
||||
const rowObj = result[0];
|
||||
const columnsReturned = rowObj.columns;
|
||||
const rows = rowObj.values;
|
||||
|
||||
// 3) For each row, create a separate table
|
||||
rows.forEach((rowValues, rowIndex) => {
|
||||
// Optional heading
|
||||
el.createEl("h4", { text: `Row #${rowIndex + 1}` });
|
||||
|
||||
// Build the table for this row
|
||||
const tableEl = el.createEl("table");
|
||||
columnsReturned.forEach((colName, colIndex) => {
|
||||
const tr = tableEl.createEl("tr");
|
||||
tr.createEl("th", { text: colName });
|
||||
tr.createEl("td", { text: String(rowValues[colIndex] ?? "") });
|
||||
});
|
||||
|
||||
el.createEl("hr");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the code block parameters line by line for:
|
||||
* table: <string>
|
||||
* keyColumn: <string>
|
||||
* value: <string>
|
||||
* columns: <string> (e.g. "col1, col2, col3")
|
||||
*/
|
||||
function parseSqlParams(source: string): {
|
||||
table?: string;
|
||||
keyColumn?: string;
|
||||
value?: string;
|
||||
columns?: string;
|
||||
} {
|
||||
const lines = source.split("\n");
|
||||
const params: any = {};
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed) continue;
|
||||
const parts = trimmed.split(":").map((p) => p.trim());
|
||||
if (parts.length >= 2) {
|
||||
const key = parts[0];
|
||||
const val = parts.slice(1).join(":"); // re-join in case there's a colon
|
||||
if (["table", "keyColumn", "value", "columns"].includes(key)) {
|
||||
params[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
Loading…
Reference in a new issue