sql-testing-tools 0.2.10__py3-none-any.whl → 0.2.12__py3-none-any.whl
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/BaseAccess.py +39 -37
- sql_testing_tools/Helper.py +101 -87
- sql_testing_tools/TokenProcessing.py +57 -97
- {sql_testing_tools-0.2.10.dist-info → sql_testing_tools-0.2.12.dist-info}/METADATA +10 -4
- sql_testing_tools-0.2.12.dist-info/RECORD +9 -0
- {sql_testing_tools-0.2.10.dist-info → sql_testing_tools-0.2.12.dist-info}/WHEEL +1 -1
- sql_testing_tools-0.2.12.dist-info/licenses/LICENSE +674 -0
- sql_testing_tools-0.2.10.dist-info/RECORD +0 -8
- {sql_testing_tools-0.2.10.dist-info → sql_testing_tools-0.2.12.dist-info}/top_level.txt +0 -0
sql_testing_tools/BaseAccess.py
CHANGED
|
@@ -26,22 +26,23 @@ dbMap = {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
__db=""
|
|
29
|
+
dbiu = 'dbiu.'
|
|
29
30
|
|
|
30
31
|
def setDBName(database):
|
|
31
32
|
global __db
|
|
32
33
|
|
|
33
|
-
if isinstance(database, str) and database.startswith(
|
|
34
|
-
|
|
34
|
+
if isinstance(database, str) and database.startswith(dbiu):
|
|
35
|
+
db_version = dbMap.get(database)
|
|
35
36
|
elif isinstance(database, int):
|
|
36
|
-
|
|
37
|
-
database =
|
|
37
|
+
db_version = database
|
|
38
|
+
database = dbiu+str(database)
|
|
38
39
|
elif isinstance(database, str):
|
|
39
|
-
|
|
40
|
+
db_version = None
|
|
40
41
|
else:
|
|
41
42
|
raise Exception("Invalid database selected")
|
|
42
43
|
|
|
43
|
-
if(
|
|
44
|
-
os.system('pip install dbiu_databases=='+str(
|
|
44
|
+
if(db_version is not None):
|
|
45
|
+
os.system('pip install dbiu_databases=='+str(db_version))
|
|
45
46
|
try:
|
|
46
47
|
import dbiu_databases
|
|
47
48
|
except ImportError:
|
|
@@ -51,9 +52,7 @@ def setDBName(database):
|
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
def run(sql: str):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if __db.startswith("dbiu.") and not __db.endswith(".db"):
|
|
55
|
+
if __db.startswith(dbiu) and not __db.endswith(".db"):
|
|
57
56
|
with importlib.resources.path('dbiu_databases', "base.db") as db_path:
|
|
58
57
|
return __run(sql, db_path)
|
|
59
58
|
else:
|
|
@@ -66,7 +65,7 @@ def __run(sql: str, db: str):
|
|
|
66
65
|
con.commit()
|
|
67
66
|
return cur
|
|
68
67
|
|
|
69
|
-
def runFromFile(path: str):
|
|
68
|
+
def runFromFile(path: str, limit: int = None):
|
|
70
69
|
sql = getSQLFromFile(path)
|
|
71
70
|
if not sql:
|
|
72
71
|
raise Exception("\nSQL-Datei ist leer. Aufgabe wurde noch nicht bearbeitet.")
|
|
@@ -81,15 +80,19 @@ def runFromFile(path: str):
|
|
|
81
80
|
raise Exception(f"\n\nSyntax-Fehler in der SQL-Abfrage:\n{str(e)}")
|
|
82
81
|
|
|
83
82
|
headers = [h[0] for h in res.description] if res.description else []
|
|
84
|
-
|
|
83
|
+
if limit:
|
|
84
|
+
rows = res.fetchmany(limit)
|
|
85
|
+
else:
|
|
86
|
+
rows = res.fetchall() if res else []
|
|
85
87
|
|
|
86
88
|
return headers, rows
|
|
87
89
|
|
|
88
90
|
|
|
89
|
-
def runAndGetStringTable_fromFile(path: str, count: int = 5,
|
|
91
|
+
def runAndGetStringTable_fromFile(path: str, count: int = 5, max_line_length: int = 85):
|
|
90
92
|
try:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
limit = 1000
|
|
94
|
+
headers, rows = runFromFile(path, limit)
|
|
95
|
+
result_count = len(rows)
|
|
93
96
|
rows = rows[:count]
|
|
94
97
|
s = ""
|
|
95
98
|
|
|
@@ -106,52 +109,51 @@ def runAndGetStringTable_fromFile(path: str, count: int = 5, maxLineLength: int
|
|
|
106
109
|
matrix[col].append(rows[row][col])
|
|
107
110
|
|
|
108
111
|
for col in range(len(matrix)):
|
|
109
|
-
|
|
112
|
+
max_length = max([len(str(x)) for x in matrix[col]])
|
|
110
113
|
|
|
111
114
|
for row in range(0, len(matrix[col])):
|
|
112
|
-
matrix[col][row] = str(matrix[col][row]).ljust(
|
|
115
|
+
matrix[col][row] = str(matrix[col][row]).ljust(max_length)
|
|
113
116
|
|
|
114
|
-
|
|
117
|
+
normalized_rows = []
|
|
115
118
|
spacing = " "
|
|
116
|
-
|
|
119
|
+
spacing_length = len(spacing) * (len(matrix[0]) - 1)
|
|
117
120
|
|
|
118
|
-
|
|
121
|
+
line_length = sum([len(x[0]) for x in matrix]) + spacing_length
|
|
119
122
|
|
|
120
123
|
|
|
121
124
|
|
|
122
|
-
if
|
|
123
|
-
|
|
124
|
-
maxColLength = int(maxLineLength/len(matrix))
|
|
125
|
+
if line_length > max_line_length:
|
|
126
|
+
max_col_length = int(max_line_length/len(matrix))
|
|
125
127
|
|
|
126
128
|
for col in range(len(matrix)):
|
|
127
129
|
for row in range(0, len(matrix[col])):
|
|
128
|
-
|
|
129
|
-
if
|
|
130
|
-
matrix[col][row] = matrix[col][row][:
|
|
130
|
+
cut_content = len(matrix[col][row].strip()) > max_col_length
|
|
131
|
+
if cut_content:
|
|
132
|
+
matrix[col][row] = matrix[col][row][:max_col_length-2] + ".."
|
|
131
133
|
else:
|
|
132
|
-
matrix[col][row] = matrix[col][row][:
|
|
134
|
+
matrix[col][row] = matrix[col][row][:max_col_length]
|
|
133
135
|
|
|
134
136
|
|
|
135
137
|
for row in range(min(count+1, len(matrix[0]))):
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
normalized_rows.append(spacing.join([str(matrix[col][row]) for col in range(len(matrix))]))
|
|
139
|
+
normalized_rows.insert(1, len(normalized_rows[0])*"-")
|
|
138
140
|
|
|
139
|
-
s = "\n".join(
|
|
140
|
-
s += "\n" +
|
|
141
|
+
s = "\n".join(normalized_rows[:count+2])
|
|
142
|
+
s += "\n" + normalized_rows[1]
|
|
141
143
|
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
+
if (result_count > count):
|
|
145
|
+
if result_count == limit:
|
|
146
|
+
s += "\n... mehr als " + str(limit) + " Zeilen"
|
|
147
|
+
else:
|
|
148
|
+
s += "\n... " + str(result_count - count) + " weitere Zeilen"
|
|
144
149
|
else:
|
|
145
150
|
s += "\n... keine weiteren Zeilen"
|
|
146
|
-
|
|
147
|
-
#longestLineInS = 85 # max([len(x.replace("\t", " ")) for x in s.split("\n")])
|
|
148
|
-
|
|
149
|
-
#s = "-" * longestLineInS + "\n" + s + "\n" + "-" * longestLineInS
|
|
150
151
|
s = "\n\nDiese Meldung sagt nichts über die Korrektheit der Abgabe aus!\nDie ersten " + str(
|
|
151
152
|
count) + " Zeilen des Ergebnisses der SQL-Abfrage:\n\n" + s
|
|
152
153
|
|
|
153
154
|
return s.replace("None", "NULL")
|
|
154
155
|
except Exception as ex:
|
|
156
|
+
print(ex)
|
|
155
157
|
raise ex
|
|
156
158
|
|
|
157
159
|
def getSQLFromFile(path: str):
|
sql_testing_tools/Helper.py
CHANGED
|
@@ -15,26 +15,37 @@ from sqlparse.tokens import Keyword, DML, Name, Wildcard
|
|
|
15
15
|
sql = ""
|
|
16
16
|
sol = ""
|
|
17
17
|
bd = None
|
|
18
|
+
kw_sel = 'SELECT'
|
|
19
|
+
kw_frm = 'FROM'
|
|
20
|
+
kw_by = ' BY'
|
|
21
|
+
kw_grp = 'GROUP' + kw_by
|
|
22
|
+
kw_ord = 'ORDER' + kw_by
|
|
23
|
+
kw_whr = 'WHERE'
|
|
24
|
+
kw_lim = 'LIMIT'
|
|
25
|
+
kw_hav = 'HAVING'
|
|
26
|
+
semcol = ';'
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def setup(sql_path,sol_path):
|
|
20
31
|
global sql, sol, bd
|
|
21
32
|
if(bd == None):
|
|
22
33
|
bd = Ba.getTableDict()
|
|
23
|
-
if(
|
|
24
|
-
sql = normalizeSQLQuery(Ba.getSQLFromFile(
|
|
25
|
-
if(
|
|
26
|
-
sol = normalizeSQLQuery(Ba.getSQLFromFile(
|
|
34
|
+
if(sql_path and sql_path != ""):
|
|
35
|
+
sql = normalizeSQLQuery(Ba.getSQLFromFile(sql_path), bd)
|
|
36
|
+
if(sol_path and sol_path != ""):
|
|
37
|
+
sol = normalizeSQLQuery(Ba.getSQLFromFile(sol_path), bd)
|
|
27
38
|
if(sql=='' or sol==''):
|
|
28
|
-
raise
|
|
39
|
+
raise AssertionError("\n\nSQL-Datei ist leer. Aufgabe wurde noch nicht bearbeitet.")
|
|
29
40
|
|
|
30
41
|
|
|
31
|
-
def normalizeSQLQuery(query,
|
|
42
|
+
def normalizeSQLQuery(query, base_dict):
|
|
32
43
|
try:
|
|
33
|
-
query = query.replace("\"", "'")
|
|
44
|
+
query = query.replace("\"", "'").replace("\n", " ").replace("\r", " ").replace("\t", " ").replace(" ", " ").strip()
|
|
34
45
|
parsed = sqlparse.parse(query)[0]
|
|
35
46
|
parsed.tokens = [token for token in parsed.tokens if not token.is_whitespace]
|
|
36
47
|
except Exception as e:
|
|
37
|
-
raise
|
|
48
|
+
raise AssertionError(f"\nFehler beim Parsen der SQL-Abfrage: {str(e)}")
|
|
38
49
|
|
|
39
50
|
formatted_query = []
|
|
40
51
|
alias_map = {}
|
|
@@ -43,16 +54,15 @@ def normalizeSQLQuery(query, baseDict):
|
|
|
43
54
|
for token in parsed.tokens:
|
|
44
55
|
if token.is_whitespace:
|
|
45
56
|
continue
|
|
46
|
-
elif token.ttype is Keyword and token.value.upper() ==
|
|
47
|
-
formatted_query.append(
|
|
48
|
-
|
|
49
|
-
elif isinstance(token, Identifier) and formatted_query and formatted_query[-1] == 'FROM':
|
|
57
|
+
elif token.ttype is Keyword and token.value.upper() == kw_frm:
|
|
58
|
+
formatted_query.append(kw_frm)
|
|
59
|
+
elif isinstance(token, Identifier) and formatted_query and formatted_query[-1] == kw_frm:
|
|
50
60
|
il = IdentifierList([token])
|
|
51
|
-
formatted_query.append(Tp._from(il, alias_map,
|
|
52
|
-
Tp._from(il, alias_map,
|
|
53
|
-
elif isinstance(token, IdentifierList) and formatted_query and formatted_query[-1] ==
|
|
54
|
-
formatted_query.append(Tp._from(token, alias_map,
|
|
55
|
-
Tp._from(token, alias_map,
|
|
61
|
+
formatted_query.append(Tp._from(il, alias_map, base_dict))
|
|
62
|
+
Tp._from(il, alias_map, base_dict)
|
|
63
|
+
elif isinstance(token, IdentifierList) and formatted_query and formatted_query[-1] == kw_frm:
|
|
64
|
+
formatted_query.append(Tp._from(token, alias_map, base_dict))
|
|
65
|
+
Tp._from(token, alias_map, base_dict)
|
|
56
66
|
|
|
57
67
|
formatted_query = []
|
|
58
68
|
|
|
@@ -60,40 +70,40 @@ def normalizeSQLQuery(query, baseDict):
|
|
|
60
70
|
for token in parsed.tokens:
|
|
61
71
|
if token.is_whitespace:
|
|
62
72
|
continue
|
|
63
|
-
elif token.ttype is DML and token.value.upper() ==
|
|
64
|
-
formatted_query.append(
|
|
65
|
-
elif token.ttype is Keyword and token.value.upper() ==
|
|
66
|
-
formatted_query.append(
|
|
67
|
-
elif token.ttype is Keyword and token.value.upper() ==
|
|
68
|
-
formatted_query.append(
|
|
69
|
-
elif token.ttype is Keyword and token.value.upper() ==
|
|
70
|
-
formatted_query.append(
|
|
71
|
-
elif token.ttype is Keyword and token.value.upper() ==
|
|
72
|
-
formatted_query.append(
|
|
73
|
-
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] ==
|
|
74
|
-
formatted_query.append(Tp._from(token, alias_map,
|
|
75
|
-
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] ==
|
|
76
|
-
formatted_query.append(Tp._groupby(token, alias_map,
|
|
77
|
-
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] ==
|
|
78
|
-
formatted_query.append(Tp._orderby(token, alias_map,
|
|
73
|
+
elif token.ttype is DML and token.value.upper() == kw_sel:
|
|
74
|
+
formatted_query.append(kw_sel)
|
|
75
|
+
elif token.ttype is Keyword and token.value.upper() == kw_frm:
|
|
76
|
+
formatted_query.append(kw_frm)
|
|
77
|
+
elif token.ttype is Keyword and token.value.upper() == kw_grp:
|
|
78
|
+
formatted_query.append(kw_grp)
|
|
79
|
+
elif token.ttype is Keyword and token.value.upper() == kw_ord:
|
|
80
|
+
formatted_query.append(kw_ord)
|
|
81
|
+
elif token.ttype is Keyword and token.value.upper() == kw_lim:
|
|
82
|
+
formatted_query.append(kw_lim)
|
|
83
|
+
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] == kw_frm:
|
|
84
|
+
formatted_query.append(Tp._from(token, alias_map, base_dict))
|
|
85
|
+
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] == kw_grp:
|
|
86
|
+
formatted_query.append(Tp._groupby(token, alias_map, base_dict))
|
|
87
|
+
elif (isinstance(token, IdentifierList) or isinstance(token, Identifier)) and formatted_query and formatted_query[-1] == kw_ord:
|
|
88
|
+
formatted_query.append(Tp._orderby(token, alias_map, base_dict))
|
|
79
89
|
elif isinstance(token, Where):
|
|
80
|
-
formatted_query.append(
|
|
81
|
-
formatted_query.append(Tp._where(token, alias_map,
|
|
82
|
-
elif formatted_query and formatted_query[-1] ==
|
|
90
|
+
formatted_query.append(kw_whr)
|
|
91
|
+
formatted_query.append(Tp._where(token, alias_map, base_dict))
|
|
92
|
+
elif formatted_query and formatted_query[-1] == kw_sel and (isinstance(token, IdentifierList) or isinstance(token, Function) or isinstance(token, Identifier)):
|
|
83
93
|
if isinstance(token, Function):
|
|
84
94
|
token = IdentifierList([token])
|
|
85
|
-
formatted_query.append(Tp._select(token, alias_map,
|
|
86
|
-
elif formatted_query and formatted_query[-1] ==
|
|
95
|
+
formatted_query.append(Tp._select(token, alias_map, base_dict))
|
|
96
|
+
elif formatted_query and formatted_query[-1] == kw_lim:
|
|
87
97
|
formatted_query.append(Tp._limit(token))
|
|
88
98
|
else:
|
|
89
99
|
formatted_query.append(str(token))
|
|
90
100
|
|
|
91
101
|
return " ".join(formatted_query)
|
|
92
102
|
|
|
93
|
-
def
|
|
103
|
+
def find_table_for_column(data_dict, target_value, relevant_tables):
|
|
94
104
|
l = []
|
|
95
105
|
for key, value_list in data_dict.items():
|
|
96
|
-
if key.lower() in
|
|
106
|
+
if key.lower() in relevant_tables:
|
|
97
107
|
for sublist in value_list:
|
|
98
108
|
if sublist and sublist[0].lower() == target_value.lower():
|
|
99
109
|
l.append(key)
|
|
@@ -104,8 +114,8 @@ def findTableForColumn(data_dict, target_value, relevantTables):
|
|
|
104
114
|
l.append(key)
|
|
105
115
|
return l
|
|
106
116
|
|
|
107
|
-
def getTableScheme(table_name: str,
|
|
108
|
-
tab =
|
|
117
|
+
def getTableScheme(table_name: str, table_dict: dict):
|
|
118
|
+
tab = table_dict[table_name]
|
|
109
119
|
|
|
110
120
|
# Format the schema
|
|
111
121
|
schema = "(" + ",".join([f"{col[0]}:{col[1]}" for col in tab]) + ")"
|
|
@@ -118,18 +128,18 @@ def getCosetteKeyFromFile():
|
|
|
118
128
|
except FileNotFoundError:
|
|
119
129
|
return "NOKEY"
|
|
120
130
|
|
|
121
|
-
def buildAndSendCosetteRequest(
|
|
131
|
+
def buildAndSendCosetteRequest(base_dict, sql, sol):
|
|
122
132
|
|
|
123
133
|
err = ""
|
|
124
|
-
for
|
|
134
|
+
for _ in range(2):
|
|
125
135
|
try:
|
|
126
|
-
|
|
136
|
+
api_key=getCosetteKeyFromFile()
|
|
127
137
|
|
|
128
138
|
|
|
129
139
|
schema = ""
|
|
130
|
-
for tab in
|
|
131
|
-
schema += f"schema sch{tab}{getTableScheme(tab,
|
|
132
|
-
for tab in
|
|
140
|
+
for tab in base_dict.keys():
|
|
141
|
+
schema += f"schema sch{tab}{getTableScheme(tab, base_dict)};\n"
|
|
142
|
+
for tab in base_dict.keys():
|
|
133
143
|
schema += f"table {tab}(sch{tab});\n"
|
|
134
144
|
|
|
135
145
|
q1 = "query q1\n`"+sql+"`;\n"
|
|
@@ -138,29 +148,25 @@ def buildAndSendCosetteRequest(baseDict, sql, sol):
|
|
|
138
148
|
cosette = "-- random Kommentar\n" + schema + q1 + q2 + "verify q1 q2;\n"
|
|
139
149
|
print(cosette)
|
|
140
150
|
|
|
141
|
-
r = requests.post("https://demo.cosette.cs.washington.edu/solve",data={"api_key":
|
|
151
|
+
r = requests.post("https://demo.cosette.cs.washington.edu/solve",data={"api_key": api_key, "query": cosette}, verify=False)
|
|
142
152
|
|
|
143
153
|
print(r.text)
|
|
144
154
|
return (r.json()['result'],r.text)
|
|
145
|
-
#return r.json()['result']
|
|
146
|
-
|
|
147
155
|
except Exception as e:
|
|
148
156
|
err = str(e)
|
|
149
157
|
return ("ERR", err)
|
|
150
158
|
|
|
151
159
|
|
|
152
|
-
def
|
|
153
|
-
|
|
160
|
+
def check_keywords(start_word:str, end_words:list):
|
|
161
|
+
start_word = start_word.lower()
|
|
154
162
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if(startWord not in sol.lower() and startWord not in sql.lower()):
|
|
163
|
+
if(start_word not in sol.lower() and start_word not in sql.lower()):
|
|
158
164
|
return ""
|
|
159
165
|
|
|
160
|
-
if(
|
|
161
|
-
start = sql.lower().find(
|
|
166
|
+
if(start_word in sql.lower()):
|
|
167
|
+
start = sql.lower().find(start_word) + len(start_word)
|
|
162
168
|
end = -1
|
|
163
|
-
for kw in
|
|
169
|
+
for kw in end_words:
|
|
164
170
|
index = sql.lower().find(kw.lower(), start)
|
|
165
171
|
if -1 < index < end or end == -1:
|
|
166
172
|
end = index
|
|
@@ -168,12 +174,11 @@ def checkKeywords(startWord:str, endWords:list):
|
|
|
168
174
|
end = len(sql)
|
|
169
175
|
|
|
170
176
|
submission = str.strip(sql[start:end])
|
|
171
|
-
#print("'"+submission+"'")
|
|
172
177
|
|
|
173
|
-
start = sol.lower().find(
|
|
178
|
+
start = sol.lower().find(start_word) + len(start_word)
|
|
174
179
|
end = -1
|
|
175
180
|
|
|
176
|
-
for kw in
|
|
181
|
+
for kw in end_words:
|
|
177
182
|
index = sol.lower().find(kw.lower(), start)
|
|
178
183
|
if -1 < index < end or end == -1:
|
|
179
184
|
end = index
|
|
@@ -184,45 +189,54 @@ def checkKeywords(startWord:str, endWords:list):
|
|
|
184
189
|
|
|
185
190
|
if submission == solution:
|
|
186
191
|
return ""
|
|
187
|
-
return "Der '"+
|
|
192
|
+
return "Der '"+start_word+"' Teil der SQL-Abfrage ist nicht korrekt (oder nicht automatisch überprüfbar)."
|
|
188
193
|
|
|
189
194
|
|
|
190
|
-
def checkColumns(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return checkKeywords("SELECT ", ["FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
195
|
+
def checkColumns(sql_path="", sol_path=""):
|
|
196
|
+
setup(sql_path, sol_path)
|
|
197
|
+
return check_keywords(kw_sel+" ", [kw_frm, kw_whr, kw_grp, kw_ord, kw_lim, semcol, kw_hav])
|
|
194
198
|
|
|
195
199
|
|
|
196
|
-
def checkTables(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return checkKeywords("FROM ", ["SELECT", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
200
|
+
def checkTables(sql_path="", sol_path=""):
|
|
201
|
+
setup(sql_path, sol_path)
|
|
202
|
+
return check_keywords(kw_frm+" ", [kw_sel, kw_whr, kw_grp, kw_ord, kw_lim, semcol, kw_hav])
|
|
200
203
|
|
|
201
204
|
|
|
202
|
-
def checkCondition(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return checkKeywords("WHERE ", ["SELECT", "FROM", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
205
|
+
def checkCondition(sql_path="", sol_path=""):
|
|
206
|
+
setup(sql_path, sol_path)
|
|
207
|
+
return check_keywords(kw_whr+" ", [kw_sel, kw_frm, kw_grp, kw_ord, kw_lim, semcol, kw_hav])
|
|
206
208
|
|
|
207
209
|
|
|
208
|
-
def checkOrder(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return checkKeywords("ORDER BY ", ["SELECT", "WHERE", "GROUP BY", "FROM", "LIMIT", ";", "HAVING"])
|
|
210
|
+
def checkOrder(sql_path="", sol_path=""):
|
|
211
|
+
setup(sql_path, sol_path)
|
|
212
|
+
return check_keywords(kw_ord+" ", [kw_sel, kw_whr, kw_grp, kw_frm, kw_lim, semcol, kw_hav])
|
|
212
213
|
|
|
213
214
|
|
|
214
|
-
def checkGroup(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
return checkKeywords("GROUP BY ", ["SELECT", "WHERE", "FROM BY", "ORDER BY", "LIMIT", ";", "HAVING"])
|
|
215
|
+
def checkGroup(sql_path="", sol_path=""):
|
|
216
|
+
setup(sql_path, sol_path)
|
|
217
|
+
return check_keywords(kw_grp+" ", [kw_sel, kw_whr, kw_grp, kw_ord, kw_lim, semcol, kw_hav])
|
|
218
218
|
|
|
219
219
|
|
|
220
|
-
def checkEquality(
|
|
221
|
-
|
|
222
|
-
setup(sqlPath, solPath)
|
|
220
|
+
def checkEquality(sql_path="", sol_path=""):
|
|
221
|
+
setup(sql_path, sol_path)
|
|
223
222
|
|
|
224
223
|
if sql == sol:
|
|
225
224
|
return ""
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
sql_build_fail = ""
|
|
228
|
+
sol_build_fail = ""
|
|
229
|
+
try:
|
|
230
|
+
Ba.runAndGetStringTable_fromFile(sql_path)
|
|
231
|
+
except Exception as e:
|
|
232
|
+
sql_build_fail = str(e)
|
|
233
|
+
try:
|
|
234
|
+
Ba.runAndGetStringTable_fromFile(sol_path)
|
|
235
|
+
except Exception as e:
|
|
236
|
+
sol_build_fail = str(e)
|
|
237
|
+
|
|
238
|
+
if(sql_build_fail != "" or sol_build_fail != ""):
|
|
239
|
+
return "\n\nFehler beim Ausführen der Abfrage. Vermutlich enthält die Abfrage Syntaxfehler:\n" + sql_build_fail + "\n" + sol_build_fail
|
|
226
240
|
|
|
227
241
|
result = buildAndSendCosetteRequest(bd, sql, sol)
|
|
228
242
|
|