This repository has been archived on 2026-10-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
shutter-view-api/lib/python3.9/site-packages/sqlparse/formatter.py
T
2022-12-10 21:17:54 -06:00

212 lines
7.3 KiB
Python

#
# Copyright (C) 2009-2020 the sqlparse authors and contributors
# <see AUTHORS file>
#
# This module is part of python-sqlparse and is released under
# the BSD License: https://opensource.org/licenses/BSD-3-Clause
"""SQL formatter"""
from sqlparse import filters
from sqlparse.exceptions import SQLParseError
def validate_options(options):
"""Validates options."""
kwcase = options.get("keyword_case")
if kwcase not in [None, "upper", "lower", "capitalize"]:
raise SQLParseError("Invalid value for keyword_case: " "{!r}".format(kwcase))
idcase = options.get("identifier_case")
if idcase not in [None, "upper", "lower", "capitalize"]:
raise SQLParseError("Invalid value for identifier_case: " "{!r}".format(idcase))
ofrmt = options.get("output_format")
if ofrmt not in [None, "sql", "python", "php"]:
raise SQLParseError("Unknown output format: " "{!r}".format(ofrmt))
strip_comments = options.get("strip_comments", False)
if strip_comments not in [True, False]:
raise SQLParseError(
"Invalid value for strip_comments: " "{!r}".format(strip_comments)
)
space_around_operators = options.get("use_space_around_operators", False)
if space_around_operators not in [True, False]:
raise SQLParseError(
"Invalid value for use_space_around_operators: "
"{!r}".format(space_around_operators)
)
strip_ws = options.get("strip_whitespace", False)
if strip_ws not in [True, False]:
raise SQLParseError(
"Invalid value for strip_whitespace: " "{!r}".format(strip_ws)
)
truncate_strings = options.get("truncate_strings")
if truncate_strings is not None:
try:
truncate_strings = int(truncate_strings)
except (ValueError, TypeError):
raise SQLParseError(
"Invalid value for truncate_strings: " "{!r}".format(truncate_strings)
)
if truncate_strings <= 1:
raise SQLParseError(
"Invalid value for truncate_strings: " "{!r}".format(truncate_strings)
)
options["truncate_strings"] = truncate_strings
options["truncate_char"] = options.get("truncate_char", "[...]")
indent_columns = options.get("indent_columns", False)
if indent_columns not in [True, False]:
raise SQLParseError(
"Invalid value for indent_columns: " "{!r}".format(indent_columns)
)
elif indent_columns:
options["reindent"] = True # enforce reindent
options["indent_columns"] = indent_columns
reindent = options.get("reindent", False)
if reindent not in [True, False]:
raise SQLParseError("Invalid value for reindent: " "{!r}".format(reindent))
elif reindent:
options["strip_whitespace"] = True
reindent_aligned = options.get("reindent_aligned", False)
if reindent_aligned not in [True, False]:
raise SQLParseError(
"Invalid value for reindent_aligned: " "{!r}".format(reindent)
)
elif reindent_aligned:
options["strip_whitespace"] = True
indent_after_first = options.get("indent_after_first", False)
if indent_after_first not in [True, False]:
raise SQLParseError(
"Invalid value for indent_after_first: " "{!r}".format(indent_after_first)
)
options["indent_after_first"] = indent_after_first
indent_tabs = options.get("indent_tabs", False)
if indent_tabs not in [True, False]:
raise SQLParseError(
"Invalid value for indent_tabs: " "{!r}".format(indent_tabs)
)
elif indent_tabs:
options["indent_char"] = "\t"
else:
options["indent_char"] = " "
indent_width = options.get("indent_width", 2)
try:
indent_width = int(indent_width)
except (TypeError, ValueError):
raise SQLParseError("indent_width requires an integer")
if indent_width < 1:
raise SQLParseError("indent_width requires a positive integer")
options["indent_width"] = indent_width
wrap_after = options.get("wrap_after", 0)
try:
wrap_after = int(wrap_after)
except (TypeError, ValueError):
raise SQLParseError("wrap_after requires an integer")
if wrap_after < 0:
raise SQLParseError("wrap_after requires a positive integer")
options["wrap_after"] = wrap_after
comma_first = options.get("comma_first", False)
if comma_first not in [True, False]:
raise SQLParseError("comma_first requires a boolean value")
options["comma_first"] = comma_first
right_margin = options.get("right_margin")
if right_margin is not None:
try:
right_margin = int(right_margin)
except (TypeError, ValueError):
raise SQLParseError("right_margin requires an integer")
if right_margin < 10:
raise SQLParseError("right_margin requires an integer > 10")
options["right_margin"] = right_margin
return options
def build_filter_stack(stack, options):
"""Setup and return a filter stack.
Args:
stack: :class:`~sqlparse.filters.FilterStack` instance
options: Dictionary with options validated by validate_options.
"""
# Token filter
if options.get("keyword_case"):
stack.preprocess.append(filters.KeywordCaseFilter(options["keyword_case"]))
if options.get("identifier_case"):
stack.preprocess.append(
filters.IdentifierCaseFilter(options["identifier_case"])
)
if options.get("truncate_strings"):
stack.preprocess.append(
filters.TruncateStringFilter(
width=options["truncate_strings"], char=options["truncate_char"]
)
)
if options.get("use_space_around_operators", False):
stack.enable_grouping()
stack.stmtprocess.append(filters.SpacesAroundOperatorsFilter())
# After grouping
if options.get("strip_comments"):
stack.enable_grouping()
stack.stmtprocess.append(filters.StripCommentsFilter())
if options.get("strip_whitespace") or options.get("reindent"):
stack.enable_grouping()
stack.stmtprocess.append(filters.StripWhitespaceFilter())
if options.get("reindent"):
stack.enable_grouping()
stack.stmtprocess.append(
filters.ReindentFilter(
char=options["indent_char"],
width=options["indent_width"],
indent_after_first=options["indent_after_first"],
indent_columns=options["indent_columns"],
wrap_after=options["wrap_after"],
comma_first=options["comma_first"],
)
)
if options.get("reindent_aligned", False):
stack.enable_grouping()
stack.stmtprocess.append(
filters.AlignedIndentFilter(char=options["indent_char"])
)
if options.get("right_margin"):
stack.enable_grouping()
stack.stmtprocess.append(
filters.RightMarginFilter(width=options["right_margin"])
)
# Serializer
if options.get("output_format"):
frmt = options["output_format"]
if frmt.lower() == "php":
fltr = filters.OutputPHPFilter()
elif frmt.lower() == "python":
fltr = filters.OutputPythonFilter()
else:
fltr = None
if fltr is not None:
stack.postprocess.append(fltr)
return stack