sql-testing-tools 0.2.4a0__tar.gz → 0.2.6__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.
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.2
2
+ Name: sql_testing_tools
3
+ Version: 0.2.6
4
+ Description-Content-Type: text/markdown
5
+ Requires-Dist: sqlparse>=0.5.1
6
+ Requires-Dist: requests>=2.32.3
7
+ Dynamic: description
8
+ Dynamic: description-content-type
9
+ Dynamic: requires-dist
10
+
11
+ A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
12
+
13
+ #### [Beta in Development!]
14
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
15
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
16
+
17
+ - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
18
+ - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
19
+
20
+
21
+ ## Getting started
22
+
23
+ ### Imports
24
+ ``` python
25
+ # ensure to always use the latest version of sql_testing_tools
26
+ import os
27
+ os.system('pip install -U sql_testing_tools')
28
+
29
+ # import sql_testing_tools
30
+ import sql_testing_tools.BaseAccess as Ba
31
+ import sql_testing_tools.Helper as He
32
+
33
+ # import unittest and create TestClass
34
+ import unittest
35
+ class TestClass(unittest.TestCase):
36
+ # Ba.setDBName(...)
37
+ # ...
38
+ ```
39
+
40
+ ### Choosing a database
41
+
42
+ On top level of your test class, set the SQLite database you want to use.
43
+
44
+ **Option 1:** Use the predefined ones from [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases) which are based on [datenbanken-im-unterricht.de](https://www.datenbanken-im-unterricht.de/catalog.php)
45
+
46
+ ``` python
47
+ # with DB name (preferred)
48
+ # --> only available if current dbiu_databases version has been imported to sql_testing_tools
49
+ Ba.setDBName("dbiu.bayern")
50
+
51
+ # or with dbiu_databases version number
52
+ # --> available as soon as a dbiu_databases version has been published on PyPi
53
+ Ba.setDBName(2)
54
+ ```
55
+
56
+ Currently supported to use with DB name are:
57
+ 1. `dbiu.bahn`: https://www.dbiu.de/bahn
58
+ 2. `dbiu.bayern`: https://www.dbiu.de/bayern
59
+ 3. `dbiu.bundestag`: https://www.datenbanken-im-unterricht.de/downloads/bundestag.zip
60
+ 4. `dbiu.bundestag_einfach`: https://www.dbiu.de/bundestagsmitglieder
61
+ 5. `dbiu.film_fernsehen`: https://www.dbiu.de/filmundfernsehen
62
+ 6. `dbiu.haushaltsausstattung`: https://www.dbiu.de/haushaltsausstattung
63
+ 7. `dbiu.straftaten`: https://www.datenbanken-im-unterricht.de/downloads/kriminalstatistik-erweitert.zip
64
+ 8. `dbiu.straftaten_einfach`: https://www.dbiu.de/kriminalstatistik
65
+ 9. `dbiu.kunstsammlung`: https://www.dbiu.de/kunstsammlung
66
+ 10. `dbiu.ladepunkte`: https://www.dbiu.de/ladepunkte
67
+ 11. `dbiu.laenderspiele`: https://www.dbiu.de/laenderspiele
68
+ 12. `dbiu.lebensmittel`: https://www.dbiu.de/lebensmittel
69
+ 13. `dbiu.schulstatistik`: https://www.dbiu.de/schulstatistik
70
+ 14. `dbiu.studierende`: https://www.dbiu.de/studierende
71
+ 15. `dbiu.unfallstatistik`: https://www.dbiu.de/unfallstatistik
72
+ 16. `dbiu.videospiele_einfach`: https://www.dbiu.de/videospiele
73
+ 17. `dbiu.videospiele`: https://www.dbiu.de/videospiele2
74
+ 18. `dbiu.wetterdaten`: https://www.dbiu.de/wetterdaten
75
+
76
+ **Option 2:** Use your own SQLite database with relative path starting at the working dir of your test repository.
77
+ ``` python
78
+ Ba.setDBName("databases/bayern.db")
79
+ ```
80
+
81
+ ### Available testing features
82
+
83
+ The following methods are available for use in test methods:
84
+
85
+
86
+ **Run the query to find out if syntax/database errors occur.**
87
+ ``` python
88
+ try:
89
+ Ba.runAndGetStringTable_fromFile("sqlfile.sql")
90
+ except Exception as e:
91
+ # the execution failed (usually due to syntax or database errors)
92
+ self.fail(e)
93
+ ```
94
+
95
+
96
+
97
+ **Set sql files to be compared (optional).**
98
+ The sql strings will be normalized and used or all following methods (to improve performance) until new files are specified. All check...() functions call setup(...) as first step. If one argument is `""` or `None` the corresponding file is not changed. Therefore calling the check...() functions without arguments does not change the sql files that are compared.
99
+ ``` python
100
+ # Raises an Exception if one of the files is empty.
101
+ setup("sqlfile.sql","solution.sql")
102
+ ```
103
+
104
+ **Compared single parts of a sql query**
105
+ Call without arguments to keep the last normalized sql strings (and improve performance) and with one or two sql file paths to load and normalize new queries.
106
+ Each check was successfull if `""` is returned. Returns a German error message if not.
107
+ Each method compares the normalized string between the start keyword and the next keyword or ;
108
+ ``` python
109
+
110
+ res = He.checkColumns() # starts at "SELECT"
111
+ res = He.checkTables() # starts at "FROM"
112
+ res = He.checkCondition() # starts at "WHERE"
113
+ res = He.checkOrder() # starts at "ORDER BY"
114
+ res = He.checkGroup() # starts at "GROUP BY"
115
+ ```
116
+
117
+ In special cases where you'd like to start and stop at individual keywords for comparison use this directly:
118
+ ``` python
119
+ # Can not be called with new sql files. If needed call setup(...) before.
120
+ res = checkKeywords("startKeyword",["end","keywords"])
121
+ ```
122
+
123
+ Compares equality of the full normalized sql strings and if not equal uses the Cosette API (cosette.cs.washington.edu) for comparison. A file `cosette_apikey.txt` with only the apikey in it on root level of the test repository is required to use this feature. If not existant, only the string comparison is performed. *Warning: Cosette is currently not maintained!*
124
+
125
+ ``` python
126
+ res = checkEquality()
127
+ ```
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+ ### Changelog
138
+
139
+ ##### V 0.2.6
140
+ - Fixed bug in checkKeywords: if keyword was present in one query and not in the other, the comparison was not performed correctly.
141
+
142
+ ##### V 0.2.5
143
+ - Added support for [dbiu.de](https://www.datenbanken-im-unterricht.de/catalog.php) databases 1-18 (loaded via [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases)) with option to still load DBs from local repo.
144
+ - Improved docs
145
+
146
+ ##### V 0.2.4
147
+ - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
148
+
149
+ ##### V 0.2.3
150
+ - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
151
+ - Verified that ; and whitespaces, linebreaks at end of query are ignored
152
+
153
+ ##### V 0.2.2
154
+ - Support LIKE
155
+ - Support '<=' and '>=' (geq and leq)
156
+
157
+ ##### V 0.2.1
158
+ - Support LIMIT
159
+
160
+ ##### V 0.1.9 + 0.2.0
161
+ - Support ORDER BY
162
+
163
+ ##### V 0.1.8
164
+ - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
165
+
166
+ ##### V 0.1.6 + V 0.1.7
167
+ - Fixed import error to ensure imports working in different environments
168
+
169
+ ##### V 0.1.4 + V 0.1.5
170
+ - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
171
+ - Aggregate Functions
172
+
173
+ ##### V 0.1.3
174
+ - SELECT: columns with our without table prefix
175
+ - FROM: one or more table from DB; no queries as tables!
176
+ - WHERE: single conditions; no Paranthesises!
177
+ - GROUP BY one or more columns
178
+
@@ -0,0 +1,168 @@
1
+ A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
2
+
3
+ #### [Beta in Development!]
4
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
5
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
6
+
7
+ - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
8
+ - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
9
+
10
+
11
+ ## Getting started
12
+
13
+ ### Imports
14
+ ``` python
15
+ # ensure to always use the latest version of sql_testing_tools
16
+ import os
17
+ os.system('pip install -U sql_testing_tools')
18
+
19
+ # import sql_testing_tools
20
+ import sql_testing_tools.BaseAccess as Ba
21
+ import sql_testing_tools.Helper as He
22
+
23
+ # import unittest and create TestClass
24
+ import unittest
25
+ class TestClass(unittest.TestCase):
26
+ # Ba.setDBName(...)
27
+ # ...
28
+ ```
29
+
30
+ ### Choosing a database
31
+
32
+ On top level of your test class, set the SQLite database you want to use.
33
+
34
+ **Option 1:** Use the predefined ones from [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases) which are based on [datenbanken-im-unterricht.de](https://www.datenbanken-im-unterricht.de/catalog.php)
35
+
36
+ ``` python
37
+ # with DB name (preferred)
38
+ # --> only available if current dbiu_databases version has been imported to sql_testing_tools
39
+ Ba.setDBName("dbiu.bayern")
40
+
41
+ # or with dbiu_databases version number
42
+ # --> available as soon as a dbiu_databases version has been published on PyPi
43
+ Ba.setDBName(2)
44
+ ```
45
+
46
+ Currently supported to use with DB name are:
47
+ 1. `dbiu.bahn`: https://www.dbiu.de/bahn
48
+ 2. `dbiu.bayern`: https://www.dbiu.de/bayern
49
+ 3. `dbiu.bundestag`: https://www.datenbanken-im-unterricht.de/downloads/bundestag.zip
50
+ 4. `dbiu.bundestag_einfach`: https://www.dbiu.de/bundestagsmitglieder
51
+ 5. `dbiu.film_fernsehen`: https://www.dbiu.de/filmundfernsehen
52
+ 6. `dbiu.haushaltsausstattung`: https://www.dbiu.de/haushaltsausstattung
53
+ 7. `dbiu.straftaten`: https://www.datenbanken-im-unterricht.de/downloads/kriminalstatistik-erweitert.zip
54
+ 8. `dbiu.straftaten_einfach`: https://www.dbiu.de/kriminalstatistik
55
+ 9. `dbiu.kunstsammlung`: https://www.dbiu.de/kunstsammlung
56
+ 10. `dbiu.ladepunkte`: https://www.dbiu.de/ladepunkte
57
+ 11. `dbiu.laenderspiele`: https://www.dbiu.de/laenderspiele
58
+ 12. `dbiu.lebensmittel`: https://www.dbiu.de/lebensmittel
59
+ 13. `dbiu.schulstatistik`: https://www.dbiu.de/schulstatistik
60
+ 14. `dbiu.studierende`: https://www.dbiu.de/studierende
61
+ 15. `dbiu.unfallstatistik`: https://www.dbiu.de/unfallstatistik
62
+ 16. `dbiu.videospiele_einfach`: https://www.dbiu.de/videospiele
63
+ 17. `dbiu.videospiele`: https://www.dbiu.de/videospiele2
64
+ 18. `dbiu.wetterdaten`: https://www.dbiu.de/wetterdaten
65
+
66
+ **Option 2:** Use your own SQLite database with relative path starting at the working dir of your test repository.
67
+ ``` python
68
+ Ba.setDBName("databases/bayern.db")
69
+ ```
70
+
71
+ ### Available testing features
72
+
73
+ The following methods are available for use in test methods:
74
+
75
+
76
+ **Run the query to find out if syntax/database errors occur.**
77
+ ``` python
78
+ try:
79
+ Ba.runAndGetStringTable_fromFile("sqlfile.sql")
80
+ except Exception as e:
81
+ # the execution failed (usually due to syntax or database errors)
82
+ self.fail(e)
83
+ ```
84
+
85
+
86
+
87
+ **Set sql files to be compared (optional).**
88
+ The sql strings will be normalized and used or all following methods (to improve performance) until new files are specified. All check...() functions call setup(...) as first step. If one argument is `""` or `None` the corresponding file is not changed. Therefore calling the check...() functions without arguments does not change the sql files that are compared.
89
+ ``` python
90
+ # Raises an Exception if one of the files is empty.
91
+ setup("sqlfile.sql","solution.sql")
92
+ ```
93
+
94
+ **Compared single parts of a sql query**
95
+ Call without arguments to keep the last normalized sql strings (and improve performance) and with one or two sql file paths to load and normalize new queries.
96
+ Each check was successfull if `""` is returned. Returns a German error message if not.
97
+ Each method compares the normalized string between the start keyword and the next keyword or ;
98
+ ``` python
99
+
100
+ res = He.checkColumns() # starts at "SELECT"
101
+ res = He.checkTables() # starts at "FROM"
102
+ res = He.checkCondition() # starts at "WHERE"
103
+ res = He.checkOrder() # starts at "ORDER BY"
104
+ res = He.checkGroup() # starts at "GROUP BY"
105
+ ```
106
+
107
+ In special cases where you'd like to start and stop at individual keywords for comparison use this directly:
108
+ ``` python
109
+ # Can not be called with new sql files. If needed call setup(...) before.
110
+ res = checkKeywords("startKeyword",["end","keywords"])
111
+ ```
112
+
113
+ Compares equality of the full normalized sql strings and if not equal uses the Cosette API (cosette.cs.washington.edu) for comparison. A file `cosette_apikey.txt` with only the apikey in it on root level of the test repository is required to use this feature. If not existant, only the string comparison is performed. *Warning: Cosette is currently not maintained!*
114
+
115
+ ``` python
116
+ res = checkEquality()
117
+ ```
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+ ### Changelog
128
+
129
+ ##### V 0.2.6
130
+ - Fixed bug in checkKeywords: if keyword was present in one query and not in the other, the comparison was not performed correctly.
131
+
132
+ ##### V 0.2.5
133
+ - Added support for [dbiu.de](https://www.datenbanken-im-unterricht.de/catalog.php) databases 1-18 (loaded via [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases)) with option to still load DBs from local repo.
134
+ - Improved docs
135
+
136
+ ##### V 0.2.4
137
+ - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
138
+
139
+ ##### V 0.2.3
140
+ - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
141
+ - Verified that ; and whitespaces, linebreaks at end of query are ignored
142
+
143
+ ##### V 0.2.2
144
+ - Support LIKE
145
+ - Support '<=' and '>=' (geq and leq)
146
+
147
+ ##### V 0.2.1
148
+ - Support LIMIT
149
+
150
+ ##### V 0.1.9 + 0.2.0
151
+ - Support ORDER BY
152
+
153
+ ##### V 0.1.8
154
+ - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
155
+
156
+ ##### V 0.1.6 + V 0.1.7
157
+ - Fixed import error to ensure imports working in different environments
158
+
159
+ ##### V 0.1.4 + V 0.1.5
160
+ - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
161
+ - Aggregate Functions
162
+
163
+ ##### V 0.1.3
164
+ - SELECT: columns with our without table prefix
165
+ - FROM: one or more table from DB; no queries as tables!
166
+ - WHERE: single conditions; no Paranthesises!
167
+ - GROUP BY one or more columns
168
+
@@ -0,0 +1,17 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r") as fh:
4
+ description = fh.read()
5
+
6
+
7
+ setup(
8
+ name='sql_testing_tools',
9
+ version='0.2.6',
10
+ packages=find_packages(),
11
+ install_requires=[
12
+ 'sqlparse>=0.5.1',
13
+ 'requests>=2.32.3'
14
+ ],
15
+ long_description=description,
16
+ long_description_content_type="text/markdown"
17
+ )
@@ -3,51 +3,68 @@ import os
3
3
  import importlib
4
4
 
5
5
 
6
- __db=""
7
6
 
8
- def setDBName(path: str):
9
- global __db
10
- print("Setting DB to: " + path)
11
- __db = path
7
+ dbMap = {
8
+ "dbiu.bahn":1,
9
+ "dbiu.bayern":2,
10
+ "dbiu.bundestag": 3,
11
+ "dbiu.bundestag_einfach": 4,
12
+ "dbiu.film_fernsehen": 5,
13
+ "dbiu.haushaltsausstattung": 6,
14
+ "dbiu.straftaten": 7,
15
+ "dbiu.straftaten_einfach": 8,
16
+ "dbiu.kunstsammlung": 9,
17
+ "dbiu.ladepunkte": 10,
18
+ "dbiu.laenderspiele": 11,
19
+ "dbiu.lebensmittel": 12,
20
+ "dbiu.schulstatistik": 13,
21
+ "dbiu.studierende": 14,
22
+ "dbiu.unfallstatistik": 15,
23
+ "dbiu.videospiele_einfach": 16,
24
+ "dbiu.videospiele": 17,
25
+ "dbiu.wetterdaten": 18
26
+ }
12
27
 
13
- def checkDbInResources():
14
- global __db
15
-
16
- resources = list(importlib.resources.contents('sql_testing_tools.databases'))
17
- print("Available resources: " + str(resources))
28
+ __db=""
18
29
 
19
- newPath = __db.replace("databases/","")
30
+ def setDBName(database):
31
+ global __db
20
32
 
21
- if(newPath not in resources):
22
- print("Database not in resources. Trying to find '"+ __db +"' in the current directory.")
23
- for root, dirs, files in os.walk('.'):
24
- for file in files:
25
- f = os.path.join(root, file)
26
- print(f)
27
- if f.endswith(newPath):
28
- print("Database found in current directory.")
29
- return False
33
+ if isinstance(database, str) and database.startswith("dbiu."):
34
+ dbVersion = dbMap.get(database)
35
+ elif isinstance(database, int):
36
+ dbVersion = database
37
+ database = "dbiu."+str(database)
38
+ elif isinstance(database, str):
39
+ dbVersion = None
30
40
  else:
31
- print("Database found in resources.")
32
- __db = newPath
33
- return True
34
-
35
-
41
+ raise Exception("Invalid database selected")
42
+
43
+ if(dbVersion is not None):
44
+ os.system('pip install dbiu_databases=='+str(dbVersion))
45
+ try:
46
+ import dbiu_databases
47
+ except ImportError:
48
+ raise Exception("Invalid database selected")
49
+ print("Setting DB to: " + database)
50
+ __db = database
51
+
52
+
36
53
  def run(sql: str):
37
54
  global __db
38
- if checkDbInResources():
39
- with importlib.resources.path('sql_testing_tools.databases', __db) as db_path:
40
- with sqlite3.connect(db_path) as con:
41
- cur = con.cursor()
42
- cur.execute(sql)
43
- con.commit()
44
- return cur
55
+
56
+ if __db.startswith("dbiu.") and not __db.endswith(".db"):
57
+ with importlib.resources.path('dbiu_databases', "base.db") as db_path:
58
+ return __run(sql, db_path)
45
59
  else:
46
- with sqlite3.connect(__db) as con:
47
- cur = con.cursor()
48
- cur.execute(sql)
49
- con.commit()
50
- return cur
60
+ return __run(sql, __db)
61
+
62
+ def __run(sql: str, db: str):
63
+ with sqlite3.connect(db) as con:
64
+ cur = con.cursor()
65
+ cur.execute(sql)
66
+ con.commit()
67
+ return cur
51
68
 
52
69
  def runFromFile(path: str):
53
70
  sql = getSQLFromFile(path)
@@ -152,7 +152,7 @@ def buildAndSendCosetteRequest(baseDict, sql, sol):
152
152
  def checkKeywords(startWord:str, endWords:list):
153
153
  global sql,sol
154
154
 
155
- if(startWord not in sol or startWord not in sql):
155
+ if(startWord not in sol and startWord not in sql):
156
156
  return ""
157
157
 
158
158
  if(startWord in sql):
@@ -186,119 +186,30 @@ def checkKeywords(startWord:str, endWords:list):
186
186
  return "Der '"+startWord+"' Teil der SQL-Abfrage ist nicht korrekt (oder nicht automatisch überprüfbar)."
187
187
 
188
188
 
189
-
190
-
191
189
  def checkColumns(sqlPath="", solPath=""):
192
190
  global sql,sol
193
191
  setup(sqlPath, solPath)
194
192
  return checkKeywords("SELECT", ["FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
195
193
 
196
194
 
197
-
198
-
199
- if("SELECT" in sql and "FROM" in sql):
200
- start = str.find(sql, "SELECT")
201
- end = str.find(sql, "FROM")
202
- submission = str.strip(sql[start:end])
203
- print("'"+submission+"'")
204
-
205
- start = str.find(sol, "SELECT")
206
- end = str.find(sol, "FROM")
207
- solution = str.strip(sol[start:end])
208
- print("'"+solution+"'")
209
-
210
- if submission == solution:
211
- return ""
212
- return "Ausgegebene Spalten sind nicht korrekt (oder nicht automatisch überprüfbar)."
213
-
214
195
  def checkTables(sqlPath="", solPath=""):
215
196
  global sql,sol
216
197
  setup(sqlPath, solPath)
217
198
  return checkKeywords("FROM", ["FROM", "WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
218
199
 
219
200
 
220
-
221
-
222
- if("SELECT" in sql and "FROM" in sql):
223
- endFromKeywords = ["WHERE", "GROUP", "ORDER", "LIMIT", ";"]
224
-
225
- start = str.find(sql, "FROM")
226
- end = -1
227
-
228
-
229
- for keyword in endFromKeywords:
230
- if(str.find(sql, keyword) != -1):
231
- end = str.find(sql, keyword)
232
- break
233
- if(end == -1):
234
- end = len(sql)
235
-
236
- submission = str.strip(sql[start:end])
237
- print("'"+submission+"'")
238
-
239
- start = str.find(sol, "FROM")
240
- end = -1
241
-
242
- for keyword in endFromKeywords:
243
- if(str.find(sol, keyword) != -1):
244
- end = str.find(sol, keyword)
245
- break
246
- if(end == -1):
247
- end = len(sol)
248
-
249
- solution = str.strip(sol[start:end])
250
- print("'"+solution+"'")
251
-
252
- if submission == solution:
253
- return ""
254
- return "Verwendete Tabellen sind nicht korrekt (oder nicht automatisch überprüfbar)."
255
-
256
201
  def checkCondition(sqlPath="", solPath=""):
257
202
  global sql,sol
258
203
  setup(sqlPath, solPath)
259
204
  return checkKeywords("WHERE", ["GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
260
205
 
206
+
261
207
  def checkOrder(sqlPath="", solPath=""):
262
208
  global sql,sol
263
209
  setup(sqlPath, solPath)
264
210
  return checkKeywords("ORDER BY", ["WHERE", "GROUP BY", "ORDER BY", "LIMIT", ";", "HAVING"])
265
211
 
266
212
 
267
-
268
- if("ORDER BY" in sql):
269
- endFromKeywords = ["WHERE", "GROUP", "LIMIT", ";"]
270
-
271
- start = str.find(sql, "ORDER BY")
272
- end = -1
273
-
274
-
275
- for keyword in endFromKeywords:
276
- if(str.find(sql, keyword) != -1):
277
- end = str.find(sql, keyword)
278
- break
279
- if(end == -1):
280
- end = len(sql)
281
-
282
- submission = str.strip(sql[start:end])
283
- print("'"+submission+"'")
284
-
285
- start = str.find(sol, "ORDER BY")
286
- end = -1
287
-
288
- for keyword in endFromKeywords:
289
- if(str.find(sol, keyword) != -1):
290
- end = str.find(sol, keyword)
291
- break
292
- if(end == -1):
293
- end = len(sol)
294
-
295
- solution = str.strip(sol[start:end])
296
- print("'"+solution+"'")
297
-
298
- if submission == solution:
299
- return ""
300
- return "Die Sortierung ist nicht korrekt (oder nicht automatisch überprüfbar)."
301
-
302
213
  def checkGroup(sqlPath="", solPath=""):
303
214
  global sql,sol
304
215
  setup(sqlPath, solPath)
@@ -306,17 +217,17 @@ def checkGroup(sqlPath="", solPath=""):
306
217
 
307
218
 
308
219
  def checkEquality(sqlPath="", solPath=""):
309
- global sql,sol
220
+ global sql, sol
310
221
  setup(sqlPath, solPath)
311
222
 
312
- if(sql==sol):
223
+ if sql == sol:
313
224
  return ""
314
225
 
315
226
  result = buildAndSendCosetteRequest(bd, sql, sol)
316
227
 
317
- if(result[0] == "ERR"):
228
+ if result[0] == "ERR":
318
229
  return "\n\nFehler bei der automatischen Überprüfung der Abgabe. Es kann keine Aussage über die Korrektheit der Abgabe getroffen werden."
319
- elif(result[0] != "EQ"):
230
+ elif result[0] != "EQ":
320
231
  return "\n\nDie Abgabe stimmt nicht mit der Musterlösung überein."
321
232
  return ""
322
233
 
@@ -0,0 +1,178 @@
1
+ Metadata-Version: 2.2
2
+ Name: sql_testing_tools
3
+ Version: 0.2.6
4
+ Description-Content-Type: text/markdown
5
+ Requires-Dist: sqlparse>=0.5.1
6
+ Requires-Dist: requests>=2.32.3
7
+ Dynamic: description
8
+ Dynamic: description-content-type
9
+ Dynamic: requires-dist
10
+
11
+ A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
12
+
13
+ #### [Beta in Development!]
14
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
15
+ [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
16
+
17
+ - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
18
+ - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
19
+
20
+
21
+ ## Getting started
22
+
23
+ ### Imports
24
+ ``` python
25
+ # ensure to always use the latest version of sql_testing_tools
26
+ import os
27
+ os.system('pip install -U sql_testing_tools')
28
+
29
+ # import sql_testing_tools
30
+ import sql_testing_tools.BaseAccess as Ba
31
+ import sql_testing_tools.Helper as He
32
+
33
+ # import unittest and create TestClass
34
+ import unittest
35
+ class TestClass(unittest.TestCase):
36
+ # Ba.setDBName(...)
37
+ # ...
38
+ ```
39
+
40
+ ### Choosing a database
41
+
42
+ On top level of your test class, set the SQLite database you want to use.
43
+
44
+ **Option 1:** Use the predefined ones from [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases) which are based on [datenbanken-im-unterricht.de](https://www.datenbanken-im-unterricht.de/catalog.php)
45
+
46
+ ``` python
47
+ # with DB name (preferred)
48
+ # --> only available if current dbiu_databases version has been imported to sql_testing_tools
49
+ Ba.setDBName("dbiu.bayern")
50
+
51
+ # or with dbiu_databases version number
52
+ # --> available as soon as a dbiu_databases version has been published on PyPi
53
+ Ba.setDBName(2)
54
+ ```
55
+
56
+ Currently supported to use with DB name are:
57
+ 1. `dbiu.bahn`: https://www.dbiu.de/bahn
58
+ 2. `dbiu.bayern`: https://www.dbiu.de/bayern
59
+ 3. `dbiu.bundestag`: https://www.datenbanken-im-unterricht.de/downloads/bundestag.zip
60
+ 4. `dbiu.bundestag_einfach`: https://www.dbiu.de/bundestagsmitglieder
61
+ 5. `dbiu.film_fernsehen`: https://www.dbiu.de/filmundfernsehen
62
+ 6. `dbiu.haushaltsausstattung`: https://www.dbiu.de/haushaltsausstattung
63
+ 7. `dbiu.straftaten`: https://www.datenbanken-im-unterricht.de/downloads/kriminalstatistik-erweitert.zip
64
+ 8. `dbiu.straftaten_einfach`: https://www.dbiu.de/kriminalstatistik
65
+ 9. `dbiu.kunstsammlung`: https://www.dbiu.de/kunstsammlung
66
+ 10. `dbiu.ladepunkte`: https://www.dbiu.de/ladepunkte
67
+ 11. `dbiu.laenderspiele`: https://www.dbiu.de/laenderspiele
68
+ 12. `dbiu.lebensmittel`: https://www.dbiu.de/lebensmittel
69
+ 13. `dbiu.schulstatistik`: https://www.dbiu.de/schulstatistik
70
+ 14. `dbiu.studierende`: https://www.dbiu.de/studierende
71
+ 15. `dbiu.unfallstatistik`: https://www.dbiu.de/unfallstatistik
72
+ 16. `dbiu.videospiele_einfach`: https://www.dbiu.de/videospiele
73
+ 17. `dbiu.videospiele`: https://www.dbiu.de/videospiele2
74
+ 18. `dbiu.wetterdaten`: https://www.dbiu.de/wetterdaten
75
+
76
+ **Option 2:** Use your own SQLite database with relative path starting at the working dir of your test repository.
77
+ ``` python
78
+ Ba.setDBName("databases/bayern.db")
79
+ ```
80
+
81
+ ### Available testing features
82
+
83
+ The following methods are available for use in test methods:
84
+
85
+
86
+ **Run the query to find out if syntax/database errors occur.**
87
+ ``` python
88
+ try:
89
+ Ba.runAndGetStringTable_fromFile("sqlfile.sql")
90
+ except Exception as e:
91
+ # the execution failed (usually due to syntax or database errors)
92
+ self.fail(e)
93
+ ```
94
+
95
+
96
+
97
+ **Set sql files to be compared (optional).**
98
+ The sql strings will be normalized and used or all following methods (to improve performance) until new files are specified. All check...() functions call setup(...) as first step. If one argument is `""` or `None` the corresponding file is not changed. Therefore calling the check...() functions without arguments does not change the sql files that are compared.
99
+ ``` python
100
+ # Raises an Exception if one of the files is empty.
101
+ setup("sqlfile.sql","solution.sql")
102
+ ```
103
+
104
+ **Compared single parts of a sql query**
105
+ Call without arguments to keep the last normalized sql strings (and improve performance) and with one or two sql file paths to load and normalize new queries.
106
+ Each check was successfull if `""` is returned. Returns a German error message if not.
107
+ Each method compares the normalized string between the start keyword and the next keyword or ;
108
+ ``` python
109
+
110
+ res = He.checkColumns() # starts at "SELECT"
111
+ res = He.checkTables() # starts at "FROM"
112
+ res = He.checkCondition() # starts at "WHERE"
113
+ res = He.checkOrder() # starts at "ORDER BY"
114
+ res = He.checkGroup() # starts at "GROUP BY"
115
+ ```
116
+
117
+ In special cases where you'd like to start and stop at individual keywords for comparison use this directly:
118
+ ``` python
119
+ # Can not be called with new sql files. If needed call setup(...) before.
120
+ res = checkKeywords("startKeyword",["end","keywords"])
121
+ ```
122
+
123
+ Compares equality of the full normalized sql strings and if not equal uses the Cosette API (cosette.cs.washington.edu) for comparison. A file `cosette_apikey.txt` with only the apikey in it on root level of the test repository is required to use this feature. If not existant, only the string comparison is performed. *Warning: Cosette is currently not maintained!*
124
+
125
+ ``` python
126
+ res = checkEquality()
127
+ ```
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+ ### Changelog
138
+
139
+ ##### V 0.2.6
140
+ - Fixed bug in checkKeywords: if keyword was present in one query and not in the other, the comparison was not performed correctly.
141
+
142
+ ##### V 0.2.5
143
+ - Added support for [dbiu.de](https://www.datenbanken-im-unterricht.de/catalog.php) databases 1-18 (loaded via [dbiu_databases](https://github.com/ValentinHerrmann/dbiu_databases)) with option to still load DBs from local repo.
144
+ - Improved docs
145
+
146
+ ##### V 0.2.4
147
+ - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
148
+
149
+ ##### V 0.2.3
150
+ - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
151
+ - Verified that ; and whitespaces, linebreaks at end of query are ignored
152
+
153
+ ##### V 0.2.2
154
+ - Support LIKE
155
+ - Support '<=' and '>=' (geq and leq)
156
+
157
+ ##### V 0.2.1
158
+ - Support LIMIT
159
+
160
+ ##### V 0.1.9 + 0.2.0
161
+ - Support ORDER BY
162
+
163
+ ##### V 0.1.8
164
+ - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
165
+
166
+ ##### V 0.1.6 + V 0.1.7
167
+ - Fixed import error to ensure imports working in different environments
168
+
169
+ ##### V 0.1.4 + V 0.1.5
170
+ - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
171
+ - Aggregate Functions
172
+
173
+ ##### V 0.1.3
174
+ - SELECT: columns with our without table prefix
175
+ - FROM: one or more table from DB; no queries as tables!
176
+ - WHERE: single conditions; no Paranthesises!
177
+ - GROUP BY one or more columns
178
+
@@ -1,127 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: sql_testing_tools
3
- Version: 0.2.4a0
4
- Description-Content-Type: text/markdown
5
- Requires-Dist: sqlparse>=0.5.1
6
- Requires-Dist: requests>=2.32.3
7
- Dynamic: description
8
- Dynamic: description-content-type
9
- Dynamic: requires-dist
10
-
11
- A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
12
-
13
- ### [Beta in Development!]
14
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
15
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
16
-
17
- - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
18
- - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
19
-
20
-
21
-
22
- ### Getting started
23
-
24
- Use the following code to import the SQL Testing Tools to your project:
25
- ``` python
26
- # ensure to always use the latest version of sql_testing_tools
27
- import os
28
- os.system('pip install -U sql_testing_tools')
29
-
30
- # import sql_testing_tools
31
- import sql_testing_tools.BaseAccess as Ba
32
- import sql_testing_tools.Helper as He
33
- ```
34
-
35
- On global level of your test class, set the SQLite database you want to use (bases must be located in the repository of the test class, no DBs contained in sql_testing_tools).
36
- ``` python
37
- import unittest
38
- class TestClass(unittest.TestCase):
39
- Ba.setDBName("databases/ladepunkte.db")
40
- ```
41
-
42
- The following methods are available for use in test methods:
43
- ``` python
44
- try:
45
- Ba.runAndGetStringTable_fromFile("sqlfile.sql")
46
- except Exception as e:
47
- # the execution failed
48
- # (usually due to syntax or database errors)
49
- self.fail(e)
50
-
51
- # (optional) set the files to be compared. The sql strings will
52
- # be normalized and used for all following methods (to improve
53
- # performance), until new files are set. Arguments that are
54
- # None or "" are ignored and the sql string remains the same.
55
- # Raises an Exception if one of the files is empty.
56
- setup("sqlfile.sql","solution.sql")
57
-
58
- # All following methods call setup(sql,sol) before executing
59
- # anything else. Call without arguments to keep the last
60
- # normalized sql strings (and improve performance).
61
- # Each check was successfull if "" is returned. Returns a
62
- # German error message if not.
63
- # Each method compares the normalized string between the start
64
- # keyword and the next keyword or ;
65
-
66
- res = He.checkColumns() # starts to search at keyword "SELECT"
67
- res = He.checkTables() # starts to search at keyword "FROM"
68
- res = He.checkCondition() # starts to search at keyword "WHERE"
69
- res = He.checkOrder() # starts to search at keyword "ORDER BY"
70
- res = He.checkGroup() # starts to search at keyword "GROUP BY"
71
-
72
- # can not be called with new sql files
73
- res = checkKeywords("startKeyword",["end","keywords"])
74
-
75
- # compares equality of the full normalized sql strings and if
76
- # not equal uses the Cosette API (cosette.cs.washington.edu)
77
- # for comparison. A file 'cosette_apikey.txt' with only the
78
- # apikey in it on root level of the test repository is required
79
- # to use this feature. If not existant, only the string comparison
80
- # is performed.
81
- # Warning: Cosette is not maintained!
82
- res = checkEquality()
83
- ```
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
- ### Changelog
94
-
95
- ##### V0.2.4
96
- - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
97
-
98
- ##### V 0.2.3
99
- - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
100
- - Verified that ; and whitespaces, linebreaks at end of query are ignored
101
-
102
- ##### V 0.2.2
103
- - Support LIKE
104
- - Support '<=' and '>=' (geq and leq)
105
-
106
- ##### V 0.2.1
107
- - Support LIMIT
108
-
109
- ##### V 0.1.9 + 0.2.0
110
- - Support ORDER BY
111
-
112
- ##### V 0.1.8
113
- - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
114
-
115
- ##### V 0.1.6 + V 0.1.7
116
- - Fixed import error to ensure imports working in different environments
117
-
118
- ##### V 0.1.4 + V 0.1.5
119
- - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
120
- - Aggregate Functions
121
-
122
- ##### V 0.1.3
123
- - SELECT: columns with our without table prefix
124
- - FROM: one or more table from DB; no queries as tables!
125
- - WHERE: single conditions; no Paranthesises!
126
- - GROUP BY one or more columns
127
-
@@ -1,117 +0,0 @@
1
- A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
2
-
3
- ### [Beta in Development!]
4
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
5
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
6
-
7
- - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
8
- - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
9
-
10
-
11
-
12
- ### Getting started
13
-
14
- Use the following code to import the SQL Testing Tools to your project:
15
- ``` python
16
- # ensure to always use the latest version of sql_testing_tools
17
- import os
18
- os.system('pip install -U sql_testing_tools')
19
-
20
- # import sql_testing_tools
21
- import sql_testing_tools.BaseAccess as Ba
22
- import sql_testing_tools.Helper as He
23
- ```
24
-
25
- On global level of your test class, set the SQLite database you want to use (bases must be located in the repository of the test class, no DBs contained in sql_testing_tools).
26
- ``` python
27
- import unittest
28
- class TestClass(unittest.TestCase):
29
- Ba.setDBName("databases/ladepunkte.db")
30
- ```
31
-
32
- The following methods are available for use in test methods:
33
- ``` python
34
- try:
35
- Ba.runAndGetStringTable_fromFile("sqlfile.sql")
36
- except Exception as e:
37
- # the execution failed
38
- # (usually due to syntax or database errors)
39
- self.fail(e)
40
-
41
- # (optional) set the files to be compared. The sql strings will
42
- # be normalized and used for all following methods (to improve
43
- # performance), until new files are set. Arguments that are
44
- # None or "" are ignored and the sql string remains the same.
45
- # Raises an Exception if one of the files is empty.
46
- setup("sqlfile.sql","solution.sql")
47
-
48
- # All following methods call setup(sql,sol) before executing
49
- # anything else. Call without arguments to keep the last
50
- # normalized sql strings (and improve performance).
51
- # Each check was successfull if "" is returned. Returns a
52
- # German error message if not.
53
- # Each method compares the normalized string between the start
54
- # keyword and the next keyword or ;
55
-
56
- res = He.checkColumns() # starts to search at keyword "SELECT"
57
- res = He.checkTables() # starts to search at keyword "FROM"
58
- res = He.checkCondition() # starts to search at keyword "WHERE"
59
- res = He.checkOrder() # starts to search at keyword "ORDER BY"
60
- res = He.checkGroup() # starts to search at keyword "GROUP BY"
61
-
62
- # can not be called with new sql files
63
- res = checkKeywords("startKeyword",["end","keywords"])
64
-
65
- # compares equality of the full normalized sql strings and if
66
- # not equal uses the Cosette API (cosette.cs.washington.edu)
67
- # for comparison. A file 'cosette_apikey.txt' with only the
68
- # apikey in it on root level of the test repository is required
69
- # to use this feature. If not existant, only the string comparison
70
- # is performed.
71
- # Warning: Cosette is not maintained!
72
- res = checkEquality()
73
- ```
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
- ### Changelog
84
-
85
- ##### V0.2.4
86
- - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
87
-
88
- ##### V 0.2.3
89
- - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
90
- - Verified that ; and whitespaces, linebreaks at end of query are ignored
91
-
92
- ##### V 0.2.2
93
- - Support LIKE
94
- - Support '<=' and '>=' (geq and leq)
95
-
96
- ##### V 0.2.1
97
- - Support LIMIT
98
-
99
- ##### V 0.1.9 + 0.2.0
100
- - Support ORDER BY
101
-
102
- ##### V 0.1.8
103
- - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
104
-
105
- ##### V 0.1.6 + V 0.1.7
106
- - Fixed import error to ensure imports working in different environments
107
-
108
- ##### V 0.1.4 + V 0.1.5
109
- - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
110
- - Aggregate Functions
111
-
112
- ##### V 0.1.3
113
- - SELECT: columns with our without table prefix
114
- - FROM: one or more table from DB; no queries as tables!
115
- - WHERE: single conditions; no Paranthesises!
116
- - GROUP BY one or more columns
117
-
@@ -1,27 +0,0 @@
1
- from setuptools import setup, find_packages
2
-
3
- with open("README.md", "r") as fh:
4
- description = fh.read()
5
-
6
-
7
- setup(
8
- name='sql_testing_tools',
9
- version='0.2.4.a',
10
- packages=find_packages(),
11
- install_requires=[
12
- 'sqlparse>=0.5.1',
13
- 'requests>=2.32.3'
14
- ],
15
- long_description=description,
16
- long_description_content_type="text/markdown",
17
- package_data={
18
- 'sql_testing_tools.databases': [
19
- 'databases/*.db'#,
20
- #'./databases/bayern.db',
21
- #'./databases/film_fernsehen.db',
22
- #'./databases/ladepunkte.db',
23
- #'./databases/straftaten.db',
24
- ]
25
- },
26
- include_package_data=True
27
- )
@@ -1,127 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: sql_testing_tools
3
- Version: 0.2.4a0
4
- Description-Content-Type: text/markdown
5
- Requires-Dist: sqlparse>=0.5.1
6
- Requires-Dist: requests>=2.32.3
7
- Dynamic: description
8
- Dynamic: description-content-type
9
- Dynamic: requires-dist
10
-
11
- A library that normalizes simple SQL queries and compares them first by equality of the normalized string and then using the cosette API.
12
-
13
- ### [Beta in Development!]
14
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-build.yml)
15
- [![Build and Test](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml/badge.svg)](https://github.com/ValentinHerrmann/sql_testing_tools/actions/workflows/python-unittests.yml)
16
-
17
- - Submit bug reports and features requests at: https://github.com/ValentinHerrmann/sql_testing_tools
18
- - PyPi-Package available at: https://pypi.org/project/sql-testing-tools/
19
-
20
-
21
-
22
- ### Getting started
23
-
24
- Use the following code to import the SQL Testing Tools to your project:
25
- ``` python
26
- # ensure to always use the latest version of sql_testing_tools
27
- import os
28
- os.system('pip install -U sql_testing_tools')
29
-
30
- # import sql_testing_tools
31
- import sql_testing_tools.BaseAccess as Ba
32
- import sql_testing_tools.Helper as He
33
- ```
34
-
35
- On global level of your test class, set the SQLite database you want to use (bases must be located in the repository of the test class, no DBs contained in sql_testing_tools).
36
- ``` python
37
- import unittest
38
- class TestClass(unittest.TestCase):
39
- Ba.setDBName("databases/ladepunkte.db")
40
- ```
41
-
42
- The following methods are available for use in test methods:
43
- ``` python
44
- try:
45
- Ba.runAndGetStringTable_fromFile("sqlfile.sql")
46
- except Exception as e:
47
- # the execution failed
48
- # (usually due to syntax or database errors)
49
- self.fail(e)
50
-
51
- # (optional) set the files to be compared. The sql strings will
52
- # be normalized and used for all following methods (to improve
53
- # performance), until new files are set. Arguments that are
54
- # None or "" are ignored and the sql string remains the same.
55
- # Raises an Exception if one of the files is empty.
56
- setup("sqlfile.sql","solution.sql")
57
-
58
- # All following methods call setup(sql,sol) before executing
59
- # anything else. Call without arguments to keep the last
60
- # normalized sql strings (and improve performance).
61
- # Each check was successfull if "" is returned. Returns a
62
- # German error message if not.
63
- # Each method compares the normalized string between the start
64
- # keyword and the next keyword or ;
65
-
66
- res = He.checkColumns() # starts to search at keyword "SELECT"
67
- res = He.checkTables() # starts to search at keyword "FROM"
68
- res = He.checkCondition() # starts to search at keyword "WHERE"
69
- res = He.checkOrder() # starts to search at keyword "ORDER BY"
70
- res = He.checkGroup() # starts to search at keyword "GROUP BY"
71
-
72
- # can not be called with new sql files
73
- res = checkKeywords("startKeyword",["end","keywords"])
74
-
75
- # compares equality of the full normalized sql strings and if
76
- # not equal uses the Cosette API (cosette.cs.washington.edu)
77
- # for comparison. A file 'cosette_apikey.txt' with only the
78
- # apikey in it on root level of the test repository is required
79
- # to use this feature. If not existant, only the string comparison
80
- # is performed.
81
- # Warning: Cosette is not maintained!
82
- res = checkEquality()
83
- ```
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
- ### Changelog
94
-
95
- ##### V0.2.4
96
- - Added more check methods for single parts of queries: checkColumns, checkTables, checkCondition, checkOrder, checkGroup, checkKeywords
97
-
98
- ##### V 0.2.3
99
- - fix: ASC/DESC in ORDER BY (also with multiple columns and order directions), no direction treated as ASC
100
- - Verified that ; and whitespaces, linebreaks at end of query are ignored
101
-
102
- ##### V 0.2.2
103
- - Support LIKE
104
- - Support '<=' and '>=' (geq and leq)
105
-
106
- ##### V 0.2.1
107
- - Support LIMIT
108
-
109
- ##### V 0.1.9 + 0.2.0
110
- - Support ORDER BY
111
-
112
- ##### V 0.1.8
113
- - Fixed linebreak problems: Linebreaks are now converted into whitespaces before parsing where tokens
114
-
115
- ##### V 0.1.6 + V 0.1.7
116
- - Fixed import error to ensure imports working in different environments
117
-
118
- ##### V 0.1.4 + V 0.1.5
119
- - Chained conditions (with AND,OR and Paranthesises) in WHERE statement
120
- - Aggregate Functions
121
-
122
- ##### V 0.1.3
123
- - SELECT: columns with our without table prefix
124
- - FROM: one or more table from DB; no queries as tables!
125
- - WHERE: single conditions; no Paranthesises!
126
- - GROUP BY one or more columns
127
-