Editor settings, SSH/SSL runtime, data import + table-menu loose ends (#7)
* feat: editor settings model + typed clamped defaults (Task 1) * feat: carry SSH config + ssh_password to backend DbConfig (Task 2) * feat: Change enum bulk/drop/empty + type-specific change payload builder (Task 3) * feat: csv parser + shared export util (Task 4) * feat: rustls TLS connector factory with modes + client auth (Task 5) * feat: real SSH tunnel manager (testable backend) + pool eviction hook (Task 6) * feat: table DDL fetch (sqlite + pg_dump arg builder) (Task 7) * feat: keychain SSH secrets + connection delete purge + tunnel lifecycle (Task 8) * feat: real SSH tunnel + TLS connect path for postgres/mysql (Task 9) * feat: execute_change bulk/drop/empty + get_table_ddl command (Task 10) * feat: fetch SSH secrets into dbConnect + save on connection form (Task 11) * feat: Editor settings tab UI (Task 12) * feat: QueryEditor applies editor settings live (Task 13) * feat: ImportDialog with CSV/JSON preview + column mapping (Task 14) * feat: table-menu export/empty/delete/import + queue labels + payload builder (Task 15) * fix: error sanitization, encrypted-key guard, row-indexed import errors, caps (Task 16) * docs: mark Editor Settings, SSH/SSL runtime, Data Import, table-menu loose ends shipped (Task 17) * feat: auto-refresh schema tree after schema-modifying SQL (query + queue drop) * fix: use theme-consistent red classes for danger menu items (text-error was undefined) * feat: changes queue as tab-bar popover + amber pending border * feat: redesign changes popover (visual/SQL toggle, cards, footer actions, Cmd+S) * refactor: drop per-card status label from changes popover cards * feat: green completion indicator on committed cards + auto-close tabs of dropped tables * docs: changes queue popover UX + auto schema refresh statuses
This commit is contained in:
+31
-9
@@ -149,6 +149,21 @@ const DESTRUCTIVE_KEYWORDS = new Set([
|
||||
"TRUNCATE", "CREATE", "REPLACE",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Return the first significant keyword of `sql` (uppercased) after stripping
|
||||
* comments and collapsing whitespace, or null when there is none.
|
||||
*/
|
||||
export function firstSignificantKeyword(sql: string): string | null {
|
||||
// Strip block comments /* ... */
|
||||
let stripped = sql.replace(/\/\*[\s\S]*?\*\//g, " ");
|
||||
// Strip line comments -- ...
|
||||
stripped = stripped.replace(/--[^\n]*/g, " ");
|
||||
// Collapse whitespace
|
||||
const tokens = stripped.trim().split(/\s+/);
|
||||
if (tokens.length === 0 || tokens[0].length === 0) return null;
|
||||
return tokens[0].toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether `sql` is a data-modifying statement by checking the
|
||||
* first significant keyword after stripping comments and whitespace.
|
||||
@@ -158,15 +173,22 @@ const DESTRUCTIVE_KEYWORDS = new Set([
|
||||
* accidental data loss, not malicious access.
|
||||
*/
|
||||
export function isDestructiveQuery(sql: string): boolean {
|
||||
// Strip block comments /* ... */
|
||||
let stripped = sql.replace(/\/\*[\s\S]*?\*\//g, " ");
|
||||
// Strip line comments -- ...
|
||||
stripped = stripped.replace(/--[^\n]*/g, " ");
|
||||
// Collapse whitespace
|
||||
const tokens = stripped.trim().split(/\s+/);
|
||||
if (tokens.length === 0 || tokens[0].length === 0) return false;
|
||||
const first = tokens[0].toUpperCase();
|
||||
return DESTRUCTIVE_KEYWORDS.has(first);
|
||||
const first = firstSignificantKeyword(sql);
|
||||
return first !== null && DESTRUCTIVE_KEYWORDS.has(first);
|
||||
}
|
||||
|
||||
const SCHEMA_MODIFYING_KEYWORDS = new Set([
|
||||
"CREATE", "DROP", "ALTER", "TRUNCATE",
|
||||
]);
|
||||
|
||||
/**
|
||||
* Detect whether `sql` changes the database schema (DDL) by checking the
|
||||
* first significant keyword. Used to auto-refresh the schema tree after a
|
||||
* successful query run.
|
||||
*/
|
||||
export function isSchemaModifyingQuery(sql: string): boolean {
|
||||
const k = firstSignificantKeyword(sql);
|
||||
return k !== null && SCHEMA_MODIFYING_KEYWORDS.has(k);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user