1#
2# Copyright (C) 2009-2020 the sqlparse authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of python-sqlparse and is released under
6# the BSD License: https://opensource.org/licenses/BSD-3-Clause
7
8from sqlparse import sql
9from sqlparse import tokens as T
10
11
12class OutputFilter:
13 varname_prefix = ''
14
15 def __init__(self, varname='sql'):
16 self.varname = self.varname_prefix + varname
17 self.count = 0
18
19 def _process(self, stream, varname, has_nl):
20 raise NotImplementedError
21
22 def process(self, stmt):
23 self.count += 1
24 if self.count > 1:
25 varname = f'{self.varname}{self.count}'
26 else:
27 varname = self.varname
28
29 has_nl = len(str(stmt).strip().splitlines()) > 1
30 stmt.tokens = self._process(stmt.tokens, varname, has_nl)
31 return stmt
32
33
34class OutputPythonFilter(OutputFilter):
35 def _process(self, stream, varname, has_nl):
36 # SQL query assignation to varname
37 if self.count > 1:
38 yield sql.Token(T.Whitespace, '\n')
39 yield sql.Token(T.Name, varname)
40 yield sql.Token(T.Whitespace, ' ')
41 yield sql.Token(T.Operator, '=')
42 yield sql.Token(T.Whitespace, ' ')
43 if has_nl:
44 yield sql.Token(T.Operator, '(')
45 yield sql.Token(T.Text, "'")
46
47 # Print the tokens on the quote
48 for token in stream:
49 # Token is a new line separator
50 if token.is_whitespace and '\n' in token.value:
51 # Close quote and add a new line
52 yield sql.Token(T.Text, " '")
53 yield sql.Token(T.Whitespace, '\n')
54
55 # Quote header on secondary lines
56 yield sql.Token(T.Whitespace, ' ' * (len(varname) + 4))
57 yield sql.Token(T.Text, "'")
58
59 # Indentation
60 after_lb = token.value.split('\n', 1)[1]
61 if after_lb:
62 yield sql.Token(T.Whitespace, after_lb)
63 continue
64
65 # Token has escape chars
66 elif "'" in token.value:
67 token.value = token.value.replace("'", "\\'")
68
69 # Put the token
70 yield sql.Token(T.Text, token.value)
71
72 # Close quote
73 yield sql.Token(T.Text, "'")
74 if has_nl:
75 yield sql.Token(T.Operator, ')')
76
77
78class OutputPHPFilter(OutputFilter):
79 varname_prefix = '$'
80
81 def _process(self, stream, varname, has_nl):
82 # SQL query assignation to varname (quote header)
83 if self.count > 1:
84 yield sql.Token(T.Whitespace, '\n')
85 yield sql.Token(T.Name, varname)
86 yield sql.Token(T.Whitespace, ' ')
87 if has_nl:
88 yield sql.Token(T.Whitespace, ' ')
89 yield sql.Token(T.Operator, '=')
90 yield sql.Token(T.Whitespace, ' ')
91 yield sql.Token(T.Text, '"')
92
93 # Print the tokens on the quote
94 for token in stream:
95 # Token is a new line separator
96 if token.is_whitespace and '\n' in token.value:
97 # Close quote and add a new line
98 yield sql.Token(T.Text, ' ";')
99 yield sql.Token(T.Whitespace, '\n')
100
101 # Quote header on secondary lines
102 yield sql.Token(T.Name, varname)
103 yield sql.Token(T.Whitespace, ' ')
104 yield sql.Token(T.Operator, '.=')
105 yield sql.Token(T.Whitespace, ' ')
106 yield sql.Token(T.Text, '"')
107
108 # Indentation
109 after_lb = token.value.split('\n', 1)[1]
110 if after_lb:
111 yield sql.Token(T.Whitespace, after_lb)
112 continue
113
114 # Token has escape chars
115 elif '"' in token.value:
116 token.value = token.value.replace('"', '\\"')
117
118 # Put the token
119 yield sql.Token(T.Text, token.value)
120
121 # Close quote
122 yield sql.Token(T.Text, '"')
123 yield sql.Token(T.Punctuation, ';')