/** * QueryAnalyzer (v2.17) * * Main facade for Explain Plan / SQL Lint / query history / parameterized templates. * Wraps TemplateStore + HistoryStore + Explainer + lintSql + substituteParams. */ import type { BaseAdapter } from '../adapters/base.js'; import type { DbAdapter, QueryResult } from '../types/adapter.js'; import type { LintResult, ExplainResult, QueryHistoryEntry, QueryHistoryInput, HistoryFilter, ProfileHistoryAggregate, Template, TemplateInput, QueryAnalyzerOptions } from './query-analyzer-types.js'; export type { LintResult, ExplainResult, QueryHistoryEntry, QueryHistoryInput, HistoryFilter, Template, TemplateInput, QueryAnalyzerOptions } from './query-analyzer-types.js'; export declare class QueryAnalyzer { private templates; private history; private explainer; private enabled; /** v2.19: optional callback returning the active profile name (or null). */ private profileProvider; /** v5.0.0: optional callback returning per-profile templates/history paths. * Returns `{templates, history}` paths OR `null` to fall back to constructor paths. * Path changes trigger automatic close+reopen of stores. */ private pathResolver; /** v5.0.0: track current resolved paths to detect changes. */ private currentTemplatesPath; private currentHistoryPath; /** v5.0.0: cipher keys reused when reopening stores at new paths. */ private templatesCipherKey?; private historyCipherKey?; private historyTtlDays?; private historyMaxRows?; /** v2.20: rotation old keys (set at construction, consumed by KeyRotator). */ private _templatesCipherKeyOld?; private _historyCipherKeyOld?; constructor(opts: QueryAnalyzerOptions); /** * v5.0.0: register a callback returning per-profile templates/history DB paths. * When called, the function should return `{templates, history}` paths (typically * `getProfileDbPath(activeProfile, 'templates')` + 'history'). * Return `null` to fall back to constructor-time default paths. * * The QueryAnalyzer auto-detects path changes (active profile switched) and * closes/reopens stores at the new paths. Templates written to profile A * stay in `/templates.db`; switching to profile B writes to `/templates.db`. */ setProfilePathResolver(fn: (() => { templates: string; history: string; } | null) | null): void; /** v2.20: rotation metadata accessor (consumed by KeyRotator). */ getRotationOldKeys(): { templates?: string; history?: string; }; isEnabled(): boolean; /** * v2.19: register a callback returning the currently active profile name, * or `null` when no profile is active (legacy single-DB mode). Whatever * the callback returns at recordQuery time is persisted as `profile_name`. * Pass `null` to clear. */ setProfileProvider(fn: (() => string | null) | null): void; attachAdapter(adapter: BaseAdapter, dbType: string): void; explain(sql: string, params?: unknown[]): Promise; lint(sql: string): LintResult; /** * v5.0.0: ensure stores are bound to the paths returned by the active * pathResolver. If paths changed since last call → close + reopen stores * at the new paths (SQLite requires exclusive connection per file). */ private ensureStoresAtActivePath; recordQuery(input: QueryHistoryInput): Promise; getHistory(filter?: HistoryFilter): Promise; saveTemplate(input: TemplateInput): Promise