Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
35 lines
881 B
Python
35 lines
881 B
Python
from __future__ import annotations
|
|
|
|
__all__ = [
|
|
"DatabaseError",
|
|
"ensure_select_only",
|
|
"_ensure_select_only",
|
|
]
|
|
|
|
|
|
class DatabaseError(RuntimeError):
|
|
"""Raised for database connectivity/query errors."""
|
|
|
|
|
|
def ensure_select_only(query: str) -> None:
|
|
"""Ensure a SQL query is read-only.
|
|
|
|
Args:
|
|
query: SQL string.
|
|
|
|
Raises:
|
|
DatabaseError: If the query does not appear to be a read-only SELECT.
|
|
|
|
Notes:
|
|
This is a conservative guard. It intentionally allows only statements
|
|
starting with SELECT or WITH (CTE) after stripping leading whitespace.
|
|
"""
|
|
|
|
q = query.strip().lower()
|
|
if not (q.startswith("select") or q.startswith("with")):
|
|
raise DatabaseError("Only SELECT queries are allowed")
|
|
|
|
|
|
# Backwards-compatible alias (older call sites use the underscore name).
|
|
_ensure_select_only = ensure_select_only
|