sql-testing-tools 0.2.8__tar.gz → 0.2.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/PKG-INFO +10 -3
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/README.md +9 -2
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/setup.py +1 -1
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools/Helper.py +19 -18
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools/TokenProcessing.py +36 -16
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/PKG-INFO +10 -3
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/setup.cfg +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools/BaseAccess.py +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools/__init__.py +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/SOURCES.txt +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/dependency_links.txt +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/requires.txt +0 -0
- {sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: sql_testing_tools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
Requires-Dist: sqlparse>=0.5.1
|
|
6
6
|
Requires-Dist: requests>=2.32.3
|
|
@@ -136,8 +136,15 @@ res = checkEquality()
|
|
|
136
136
|
|
|
137
137
|
### Changelog
|
|
138
138
|
|
|
139
|
-
##### V 0.2.
|
|
140
|
-
-
|
|
139
|
+
##### V 0.2.10
|
|
140
|
+
- fixed part checks if keywords are in wrong order
|
|
141
|
+
|
|
142
|
+
##### V 0.2.9
|
|
143
|
+
- added NOT support
|
|
144
|
+
- improved Parentheses handling
|
|
145
|
+
|
|
146
|
+
##### V 0.2.8
|
|
147
|
+
- ignore case in '=' string comparison and convert to LIKE (if no '%', '_' in String)
|
|
141
148
|
|
|
142
149
|
##### V 0.2.7
|
|
143
150
|
- Normalize String unequality: ...<>..., ...!=..., ...NOT LIKE... --> NOT...LIKE...
|
|
@@ -126,8 +126,15 @@ res = checkEquality()
|
|
|
126
126
|
|
|
127
127
|
### Changelog
|
|
128
128
|
|
|
129
|
-
##### V 0.2.
|
|
130
|
-
-
|
|
129
|
+
##### V 0.2.10
|
|
130
|
+
- fixed part checks if keywords are in wrong order
|
|
131
|
+
|
|
132
|
+
##### V 0.2.9
|
|
133
|
+
- added NOT support
|
|
134
|
+
- improved Parentheses handling
|
|
135
|
+
|
|
136
|
+
##### V 0.2.8
|
|
137
|
+
- ignore case in '=' string comparison and convert to LIKE (if no '%', '_' in String)
|
|
131
138
|
|
|
132
139
|
##### V 0.2.7
|
|
133
140
|
- Normalize String unequality: ...<>..., ...!=..., ...NOT LIKE... --> NOT...LIKE...
|
|
@@ -152,34 +152,35 @@ def buildAndSendCosetteRequest(baseDict, sql, sol):
|
|
|
152
152
|
def checkKeywords(startWord:str, endWords:list):
|
|
153
153
|
global sql,sol
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
startWord = startWord.lower()
|
|
156
|
+
|
|
157
|
+
if(startWord not in sol.lower() and startWord not in sql.lower()):
|
|
156
158
|
return ""
|
|
157
159
|
|
|
158
|
-
if(startWord in sql):
|
|
159
|
-
start =
|
|
160
|
+
if(startWord in sql.lower()):
|
|
161
|
+
start = sql.lower().find(startWord) + len(startWord)
|
|
160
162
|
end = -1
|
|
161
163
|
for kw in endWords:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
index = sql.lower().find(kw.lower(), start)
|
|
165
|
+
if -1 < index < end or end == -1:
|
|
166
|
+
end = index
|
|
165
167
|
if(end == -1):
|
|
166
168
|
end = len(sql)
|
|
167
169
|
|
|
168
170
|
submission = str.strip(sql[start:end])
|
|
169
|
-
print("'"+submission+"'")
|
|
171
|
+
#print("'"+submission+"'")
|
|
170
172
|
|
|
171
|
-
start =
|
|
173
|
+
start = sol.lower().find(startWord) + len(startWord)
|
|
172
174
|
end = -1
|
|
173
175
|
|
|
174
176
|
for kw in endWords:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
177
|
+
index = sol.lower().find(kw.lower(), start)
|
|
178
|
+
if -1 < index < end or end == -1:
|
|
179
|
+
end = index
|
|
178
180
|
if(end == -1):
|
|
179
181
|
end = len(sol)
|
|
180
182
|
|
|
181
183
|
solution = str.strip(sol[start:end])
|
|
182
|
-
print("'"+solution+"'")
|
|
183
184
|
|
|
184
185
|
if submission == solution:
|
|
185
186
|
return ""
|
|
@@ -189,31 +190,31 @@ def checkKeywords(startWord:str, endWords:list):
|
|
|
189
190
|
def checkColumns(sqlPath="", solPath=""):
|
|
190
191
|
global sql,sol
|
|
191
192
|
setup(sqlPath, solPath)
|
|
192
|
-
return checkKeywords("SELECT", ["FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
193
|
+
return checkKeywords("SELECT ", ["FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
193
194
|
|
|
194
195
|
|
|
195
196
|
def checkTables(sqlPath="", solPath=""):
|
|
196
197
|
global sql,sol
|
|
197
198
|
setup(sqlPath, solPath)
|
|
198
|
-
return checkKeywords("FROM", ["
|
|
199
|
+
return checkKeywords("FROM ", ["SELECT", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
199
200
|
|
|
200
201
|
|
|
201
202
|
def checkCondition(sqlPath="", solPath=""):
|
|
202
203
|
global sql,sol
|
|
203
204
|
setup(sqlPath, solPath)
|
|
204
|
-
return checkKeywords("WHERE", ["GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
205
|
+
return checkKeywords("WHERE ", ["SELECT", "FROM", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
205
206
|
|
|
206
207
|
|
|
207
208
|
def checkOrder(sqlPath="", solPath=""):
|
|
208
209
|
global sql,sol
|
|
209
210
|
setup(sqlPath, solPath)
|
|
210
|
-
return checkKeywords("ORDER BY", ["WHERE", "GROUP BY", "
|
|
211
|
+
return checkKeywords("ORDER BY ", ["SELECT", "WHERE", "GROUP BY", "FROM", "LIMIT", ";", "HAVING"])
|
|
211
212
|
|
|
212
213
|
|
|
213
214
|
def checkGroup(sqlPath="", solPath=""):
|
|
214
|
-
global sql,sol
|
|
215
|
+
global sql, sol
|
|
215
216
|
setup(sqlPath, solPath)
|
|
216
|
-
return checkKeywords("GROUP BY", ["WHERE", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
217
|
+
return checkKeywords("GROUP BY ", ["SELECT", "WHERE", "FROM BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
217
218
|
|
|
218
219
|
|
|
219
220
|
def checkEquality(sqlPath="", solPath=""):
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import sqlparse
|
|
2
|
-
from sqlparse.sql import Identifier, IdentifierList, Where, Comparison, Function, Parenthesis
|
|
2
|
+
from sqlparse.sql import Identifier, IdentifierList, Where, Comparison, Function, Parenthesis, Token
|
|
3
3
|
from sqlparse.tokens import Keyword, DML, Name, Wildcard, Whitespace, Newline
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
try:
|
|
7
6
|
import Helper as He
|
|
8
7
|
except ImportError:
|
|
@@ -115,6 +114,25 @@ def _orderby(orderby_, alias_map, baseDict: dict):
|
|
|
115
114
|
# orderby_tokens.sort()
|
|
116
115
|
return ",".join(orderby_tokens)
|
|
117
116
|
|
|
117
|
+
def replace_not_with_parenthesis(where_tokens):
|
|
118
|
+
new_tokens = []
|
|
119
|
+
i = 0
|
|
120
|
+
while i < len(where_tokens):
|
|
121
|
+
if where_tokens[i].ttype is Keyword and where_tokens[i].value.upper() == "NOT":
|
|
122
|
+
if i + 1 < len(where_tokens):
|
|
123
|
+
not_token = where_tokens[i]
|
|
124
|
+
next_token = where_tokens[i + 1]
|
|
125
|
+
parenthesis = Parenthesis([not_token, Token(Whitespace, ' '), next_token])
|
|
126
|
+
new_tokens.append(parenthesis)
|
|
127
|
+
i += 2 # Skip the next token as it is already added inside the parenthesis
|
|
128
|
+
else:
|
|
129
|
+
new_tokens.append(where_tokens[i])
|
|
130
|
+
i += 1
|
|
131
|
+
else:
|
|
132
|
+
new_tokens.append(where_tokens[i])
|
|
133
|
+
i += 1
|
|
134
|
+
return new_tokens
|
|
135
|
+
|
|
118
136
|
def _condition(token, alias_map, baseDict: dict):
|
|
119
137
|
left, operator, right = [t for t in token.tokens if not t.is_whitespace]
|
|
120
138
|
|
|
@@ -143,11 +161,11 @@ def _condition(token, alias_map, baseDict: dict):
|
|
|
143
161
|
left = _identifier(left, alias_map, baseDict)
|
|
144
162
|
right = _identifier(right, alias_map, baseDict)
|
|
145
163
|
|
|
146
|
-
if operator.value in ("!=", "<>"):
|
|
147
|
-
return f"NOT {left.lower()} LIKE {right}"
|
|
148
|
-
if operator.value
|
|
149
|
-
return f"NOT {left.lower()} LIKE {right}"
|
|
150
|
-
if operator.value
|
|
164
|
+
if operator.value.strip() in ("!=", "<>"):
|
|
165
|
+
return f"(NOT {left.lower()} LIKE {right})"
|
|
166
|
+
if operator.value.lower().strip() == "not like":
|
|
167
|
+
return f"(NOT {left.lower()} LIKE {right})"
|
|
168
|
+
if operator.value.strip() == "=" and "%" not in right and "_" not in right:
|
|
151
169
|
return f"{left.lower()} LIKE {right}"
|
|
152
170
|
|
|
153
171
|
|
|
@@ -163,7 +181,7 @@ def _condition(token, alias_map, baseDict: dict):
|
|
|
163
181
|
elif operator.value == "<=":
|
|
164
182
|
operator = ">="
|
|
165
183
|
|
|
166
|
-
return f"{left if leftLiteral else left.lower()} {operator} {right if rightLiteral else right.lower()}"
|
|
184
|
+
return f"{left if leftLiteral else left.lower()} {operator.value.upper()} {right if rightLiteral else right.lower()}"
|
|
167
185
|
|
|
168
186
|
def is_value(token):
|
|
169
187
|
return token.ttype in (sqlparse.tokens.Token.Literal.Number.Integer,
|
|
@@ -253,11 +271,14 @@ def _where(where, alias_map, baseDict: dict):
|
|
|
253
271
|
|
|
254
272
|
isParanthesis = isinstance(where, Parenthesis)
|
|
255
273
|
|
|
256
|
-
where_tokens = [token for token in where.tokens if (token.ttype is not Whitespace and token.ttype is not Newline)and token.value != "WHERE"]
|
|
274
|
+
where_tokens = [token for token in where.tokens if (token.ttype is not Whitespace and token.ttype is not Newline) and token.value != "WHERE"]
|
|
275
|
+
where_tokens = replace_not_with_parenthesis(where_tokens)
|
|
276
|
+
|
|
277
|
+
# No parentheses in where_string!
|
|
257
278
|
where_string = " ".join([str(token) for token in where_tokens])
|
|
258
279
|
|
|
259
280
|
and_count = where_string.upper().count(" AND ")
|
|
260
|
-
or_count
|
|
281
|
+
or_count = where_string.upper().count(" OR ")
|
|
261
282
|
|
|
262
283
|
# No AND / OR
|
|
263
284
|
if and_count + or_count == 0:
|
|
@@ -332,6 +353,8 @@ def _where_addBracketsAroundAND(where, alias_map, baseDict: dict):
|
|
|
332
353
|
def _where_simpleCondition(where_tokens, alias_map, baseDict: dict):
|
|
333
354
|
cond = []
|
|
334
355
|
for tok in where_tokens:
|
|
356
|
+
if tok.ttype == Keyword and tok.value.upper() == "NOT":
|
|
357
|
+
cond.append("NOT ")
|
|
335
358
|
if isinstance(tok, Comparison):
|
|
336
359
|
cond.append(_condition(tok, alias_map, baseDict))
|
|
337
360
|
elif isinstance(tok, Parenthesis):
|
|
@@ -346,13 +369,10 @@ def _where_sameStrengthKeywords(where_tokens, alias_map, baseDict: dict, keyword
|
|
|
346
369
|
cond = []
|
|
347
370
|
for tok in where_tokens:
|
|
348
371
|
if isinstance(tok, Comparison):
|
|
349
|
-
cond.append(
|
|
372
|
+
cond.append(_where_simpleCondition([tok], alias_map, baseDict))
|
|
350
373
|
elif isinstance(tok, Parenthesis):
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
cond.append(_condition(_tok, alias_map, baseDict))
|
|
354
|
-
elif isinstance(_tok, Parenthesis):
|
|
355
|
-
tok = _tok
|
|
374
|
+
isNot = tok.tokens[0].ttype == Keyword and tok.tokens[0].value.upper() == "NOT"
|
|
375
|
+
cond.append(("(" if isNot else "") + _where(tok, alias_map, baseDict) + (")" if isNot else ""))
|
|
356
376
|
cond.sort()
|
|
357
377
|
return keyword.join(cond)
|
|
358
378
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: sql_testing_tools
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
Requires-Dist: sqlparse>=0.5.1
|
|
6
6
|
Requires-Dist: requests>=2.32.3
|
|
@@ -136,8 +136,15 @@ res = checkEquality()
|
|
|
136
136
|
|
|
137
137
|
### Changelog
|
|
138
138
|
|
|
139
|
-
##### V 0.2.
|
|
140
|
-
-
|
|
139
|
+
##### V 0.2.10
|
|
140
|
+
- fixed part checks if keywords are in wrong order
|
|
141
|
+
|
|
142
|
+
##### V 0.2.9
|
|
143
|
+
- added NOT support
|
|
144
|
+
- improved Parentheses handling
|
|
145
|
+
|
|
146
|
+
##### V 0.2.8
|
|
147
|
+
- ignore case in '=' string comparison and convert to LIKE (if no '%', '_' in String)
|
|
141
148
|
|
|
142
149
|
##### V 0.2.7
|
|
143
150
|
- Normalize String unequality: ...<>..., ...!=..., ...NOT LIKE... --> NOT...LIKE...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/requires.txt
RENAMED
|
File without changes
|
{sql_testing_tools-0.2.8 → sql_testing_tools-0.2.10}/sql_testing_tools.egg-info/top_level.txt
RENAMED
|
File without changes
|