-
Notifications
You must be signed in to change notification settings - Fork 0
/
queries.py
266 lines (224 loc) · 8.16 KB
/
queries.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
"""
#!/usr/bin/env python3
Backend SQL query handler
progression_tracker_OOP_V2/queries.py
"""
import mariadb
import sqlite3
from python_datalogger import DataLogger
env_logger = DataLogger(name="QueryInfoLogger", propagate=False)
class QueryData:
"""
Main class for SQL (mariadb/sqlite3) query handling
"""
# Change the info in this dictionary according to your preferred database(mariadb).
alt_query = {
"host": 'localhost',
"user": 'db_user',
"password": 'root',
"database": 'progression_tracker_db_v2'
}
local_db = {
"database": "progression_db.db"
}
def __init__(self, host: str = alt_query["host"], user: str = alt_query["user"],
password: str = alt_query["password"], database: str = alt_query["database"],
choice: str = "local", **kwargs):
self.logger = DataLogger(name="QueryLogger", propagate=False)
self.__host = host
self.__user = user
self.__password = password
self.__database = database
self.__choice = choice
self.connect = sqlite3.connect(QueryData.local_db["database"])
env_logger.logger.propagate = True
if self.choice != "local":
try:
self.connect = mariadb.connect(
host=self.host,
user=self.user,
password=self.password,
database=self.database
)
env_logger.log_info(f"Proceeding with [alternate] foreign database [mariadb].")
except Exception as exception:
env_logger.log_error(str(exception))
env_logger.log_info("Proceeding with [default] local database [sqlite3].")
else:
self.logger.log_info("Proceeding with [default] local database [sqlite3].")
self.cursor = self.connect.cursor()
self.init_tables()
super().__init__(**kwargs)
@property
def host(self) -> str:
return self.__host
@property
def user(self) -> str:
return self.__user
@property
def password(self) -> str:
return self.__password
@property
def database(self) -> str:
return self.__database
@property
def choice(self) -> str:
return self.__choice
@staticmethod
def default_user_setup() -> str:
"""
Query to initiate the user_data table
:return: user_data table SQL query
"""
return """
CREATE TABLE IF NOT EXISTS `user_data` (
`uid` VARCHAR(200) NOT NULL ,
`name` TEXT NOT NULL ,
`password` VARCHAR(300) NOT NULL);
"""
@staticmethod
def default_user_progression_setup() -> str:
"""
Query to initiate the user_progression table
:return: user_progression table SQL query
"""
return """
CREATE TABLE IF NOT EXISTS `user_progression` (
`uid` VARCHAR(200) NOT NULL ,
`pass_marks` VARCHAR(200) NOT NULL ,
`defer_marks` VARCHAR(200) NOT NULL ,
`fail_marks` VARCHAR(200) NOT NULL ,
`outcome` VARCHAR(200) NOT NULL);
"""
# ENGINE = MyISAM;
@staticmethod
def default_user_statistics_setup() -> str:
"""
Query to initiate the user_stats table
:return: user_stats table SQL query
"""
return """
CREATE TABLE IF NOT EXISTS `user_stats` (
`progress` INT(200) NULL DEFAULT '0' ,
`trailing` INT(200) NOT NULL DEFAULT '0' ,
`retriever` INT(200) NOT NULL DEFAULT '0' ,
`exclude` INT(200) NOT NULL DEFAULT '0' );
"""
def execute(self, func: any = None, output: bool = False) -> list:
"""
Executes a SQL query based on user preference
:param func: Specific SQL query
:param output: boolean value of output choice (True or False)
:return: if output is True, returns fetched results
"""
if func is not None:
self.cursor.execute(func)
self.connect.commit()
if output:
return self.cursor.fetchall()
else:
self.logger.log_critical(f"param: func is not specified -> {func}")
raise Exception(f"param: func is not specified -> {func}")
def init_tables(self) -> None:
"""
Initiates all the necessary data tables
:return: None
"""
self.cursor.execute(self.default_user_setup())
self.cursor.execute(self.default_user_progression_setup())
self.cursor.execute(self.default_user_statistics_setup())
@staticmethod
def read_all_queries(table_name: str) -> str:
"""
Reads all queries of a given table
:param table_name: preferred table name
:return: list of all the queries on the table
"""
return f"""
SELECT *
FROM {table_name};
"""
@staticmethod
def read_user_data_fields(table_name: str, columns: str) -> str:
"""
Reads a specific column of a given table
:param table_name: preferred table name
:param columns: required column(s)
:return: list of a selected column
"""
return f"""
SELECT {columns}
FROM {table_name};
"""
@staticmethod
def read_user_specific_field(table_name: str, filter_expression: str, column: str) -> str:
"""
Reads a specific value from a column of a given table using filter expressions
:param table_name: preferred table name
:param filter_expression: expression to filter out a specific value
:param column: required column
:return: tuple of a selected data
"""
return f"""
SELECT {column}
FROM {table_name}
WHERE {filter_expression};
"""
@staticmethod
def create_row_query(table_name: str, data_list: list) -> str:
"""
Enter a row of data to a specified table
:param table_name: preferred table name
:param data_list: list of values to be entered as a row
:return: None
"""
values_string = ", ".join(map(str, data_list))
return f"""
INSERT INTO {table_name}
VALUES ({values_string});
"""
@staticmethod
def update_rows_query(table_name: str, column_value_pair: str, filter_expression: str) -> str:
"""
Update a row of a specified table
:param table_name: preferred table name
:param column_value_pair: column and the value required to be updated
:param filter_expression: filter expression to isolate a specific value
:return: None
"""
return f"""
UPDATE {table_name}
SET {column_value_pair}
WHERE {filter_expression};
"""
@staticmethod
def delete_rows(table_name: str, filter_expression: str) -> str:
"""
Delete a specified row from a specified table
:param table_name: preferred table name
:param filter_expression: filter expression to isolate a specific row
:return: None
"""
return f"""
DELETE FROM {table_name}
WHERE {filter_expression};
"""
@staticmethod
def read_using_inner_join(table_columns: str, join_table_1: str, join_table_2: str,
common_column: str, table_filter_expression: str) -> str:
"""
Select a unique value from a given pair of tables using
inner join to match 2 common columns and by filtering out unnecessary data
:param table_columns: column from which the data is to be retrieved
:param join_table_1: preferred table 1 name
:param join_table_2: preferred table 2 name
:param common_column: column common to both table 1 and table 2
:param table_filter_expression: filter expression to isolate a specific data
:return: tuple of a selected data
"""
return f"""
SELECT {table_columns}
FROM {join_table_1} INNER JOIN {join_table_2}
ON {join_table_1}.{common_column} = {join_table_2}.{common_column}
WHERE {table_filter_expression};
"""