diff options
| author | Andi Albrecht <albrecht.andi@gmail.com> | 2016-09-14 18:42:22 +0200 |
|---|---|---|
| committer | Andi Albrecht <albrecht.andi@gmail.com> | 2016-09-14 18:42:22 +0200 |
| commit | 4d05b441fcb801d320ac52ce90465b74d419ceac (patch) | |
| tree | 0f18b1f401d1fce76be0d8403153e5616dbe573e | |
| parent | 4430c5c163d8b6ffc89d83b506c8a478037d26ea (diff) | |
| download | sqlparse-4d05b441fcb801d320ac52ce90465b74d419ceac.tar.gz | |
Add formatter option for comma first notation (fixes #141).
| -rw-r--r-- | CHANGELOG | 5 | ||||
| -rwxr-xr-x | sqlparse/cli.py | 7 | ||||
| -rw-r--r-- | sqlparse/filters/reindent.py | 17 | ||||
| -rw-r--r-- | sqlparse/formatter.py | 8 | ||||
| -rw-r--r-- | tests/test_format.py | 15 |
5 files changed, 50 insertions, 2 deletions
@@ -1,6 +1,11 @@ Development Version ------------------- +Enhancements + +* Add comma_first option: When splitting list "comma first" notation + is used (issue141). + Bug Fixes * Fix parsing of incomplete AS (issue284, by vmuriart). diff --git a/sqlparse/cli.py b/sqlparse/cli.py index 9479dd1..bd2e1b8 100755 --- a/sqlparse/cli.py +++ b/sqlparse/cli.py @@ -118,6 +118,13 @@ def create_parser(): type=int, help='Column after which lists should be wrapped') + group.add_argument( + '--comma_first', + dest='comma_first', + default=False, + type=bool, + help='Insert linebreak before comma (default False)') + return parser diff --git a/sqlparse/filters/reindent.py b/sqlparse/filters/reindent.py index dab4d03..7421f6d 100644 --- a/sqlparse/filters/reindent.py +++ b/sqlparse/filters/reindent.py @@ -11,13 +11,15 @@ from sqlparse.utils import offset, indent class ReindentFilter(object): - def __init__(self, width=2, char=' ', wrap_after=0, n='\n'): + def __init__(self, width=2, char=' ', wrap_after=0, n='\n', + comma_first=False): self.n = n self.width = width self.char = char self.indent = 0 self.offset = 0 self.wrap_after = wrap_after + self.comma_first = comma_first self._curr_stmt = None self._last_stmt = None @@ -123,7 +125,20 @@ class ReindentFilter(object): # Add 1 for the "," separator position += len(token.value) + 1 if position > (self.wrap_after - self.offset): + if self.comma_first: + _, comma = tlist.token_prev( + tlist.token_index(token)) + if comma is None: + continue + token = comma tlist.insert_before(token, self.nl()) + if self.comma_first: + _, ws = tlist.token_next( + tlist.token_index(token), skip_ws=False) + if (ws is not None + and not ws.ttype is T.Text.Whitespace): + tlist.insert_after( + token, sql.Token(T.Whitespace, ' ')) position = 0 self._process_default(tlist) diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py index 72b50eb..a58d5af 100644 --- a/sqlparse/formatter.py +++ b/sqlparse/formatter.py @@ -97,6 +97,11 @@ def validate_options(options): 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: @@ -148,7 +153,8 @@ def build_filter_stack(stack, options): stack.stmtprocess.append( filters.ReindentFilter(char=options['indent_char'], width=options['indent_width'], - wrap_after=options['wrap_after'])) + wrap_after=options['wrap_after'], + comma_first=options['comma_first'])) if options.get('reindent_aligned', False): stack.enable_grouping() diff --git a/tests/test_format.py b/tests/test_format.py index 023f26d..67377ab 100644 --- a/tests/test_format.py +++ b/tests/test_format.py @@ -322,6 +322,8 @@ class TestFormatReindent(object): sqlparse.format('foo', reindent=True, wrap_after='foo') with pytest.raises(SQLParseError): sqlparse.format('foo', reindent=True, wrap_after=-12) + with pytest.raises(SQLParseError): + sqlparse.format('foo', reindent=True, comma_first='foo') def test_stmts(self): f = lambda sql: sqlparse.format(sql, reindent=True) @@ -428,6 +430,19 @@ class TestFormatReindent(object): 'from table1, table2', 'where 1 = 2']) + def test_identifier_list_comment_first(self): + f = lambda sql: sqlparse.format(sql, reindent=True, comma_first=True) + # not the 3: It cleans up whitespace too! + s = 'select foo, bar, baz from table where foo in (1, 2,3)' + assert f(s) == '\n'.join([ + 'select foo', + ' , bar', + ' , baz', + 'from table', + 'where foo in (1', + ' , 2', + ' , 3)']) + def test_identifier_list_with_functions(self): f = lambda sql: sqlparse.format(sql, reindent=True) s = ("select 'abc' as foo, coalesce(col1, col2)||col3 as bar," |
