File size: 999 Bytes
13fe504
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
"""SQL rendering helpers for DataForge table-store adapters."""

from __future__ import annotations

import re

_SAFE_RELATION_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*|\.\"[^\"]+\")*$")
_SAFE_IDENTIFIER_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")


def ensure_safe_relation(relation: str) -> str:
    """Return a validated relation identifier or raise ``ValueError``."""
    if not _SAFE_RELATION_RE.fullmatch(relation):
        raise ValueError(f"Unsafe relation identifier: {relation}")
    return relation


def quote_identifier(identifier: str) -> str:
    """Return a double-quoted SQL identifier after strict validation."""
    if not _SAFE_IDENTIFIER_RE.fullmatch(identifier):
        raise ValueError(f"Unsafe column identifier: {identifier}")
    return f'"{identifier}"'


def sql_literal(value: object) -> str:
    """Render a SQL string literal for generated patch statements."""
    return "'" + str(value).replace("'", "''") + "'"