9
9
10
10
class SQLConditionEnum (Enum ):
11
11
"""
12
+ Enumeration for SQL comparison operator
13
+
12
14
https://www.techonthenet.com/sqlite/comparison_operators.php
13
15
"""
14
16
equal = '='
@@ -25,17 +27,46 @@ class DataBase:
25
27
"""
26
28
27
29
def __init__ (self , name : str ):
30
+ """
31
+ Initialise a DataBase instance
32
+
33
+ :param name: name of the database
34
+ :type name: str
35
+ """
28
36
self .name = name
29
37
self .logger = LoggerGenerator .get_logger (self .name )
30
38
self .save_path = get_data_path () / f"{ name } .db"
39
+ self .db_conn = None
40
+ self .db_cursor = None
41
+ self .connect ()
42
+
43
+ def connect (self ):
44
+ """
45
+ Connect to the sqlite3 database
46
+
47
+ :return: None
48
+ :rtype: None
49
+ """
31
50
self .db_conn = sqlite3 .connect (self .save_path )
32
51
self .db_cursor = self .db_conn .cursor ()
33
52
34
- def _fetch_rows (self , execution_cmd : str ):
53
+ def close (self ):
54
+ """
55
+ Close the connection with the sqlite3 database
56
+
57
+ :return: None
58
+ :rtype: None
59
+ """
60
+ self .db_conn .close ()
61
+
62
+ def _fetch_rows (self , execution_cmd : str ) -> List [Tuple ]:
35
63
"""
36
- execute a command to fetch some rows and return them
64
+ Execute a command to fetch some rows and return them
65
+
37
66
:param execution_cmd: the command to execute
38
- :return:
67
+ :type execution_cmd: str
68
+ :return: list of the table's rows selected by the command
69
+ :rtype: List[Tuple]
39
70
"""
40
71
rows = []
41
72
try :
@@ -51,10 +82,14 @@ def _fetch_rows(self, execution_cmd: str):
51
82
52
83
def get_row_by_key (self , table : Table , key_value ) -> Optional [Tuple ]:
53
84
"""
54
- get the row identified by a primary key value from a table
55
- :param table: table to fetch the row from
56
- :param key_value: key value of the row
57
- :return: None or the row of value
85
+ Get the row identified by a primary key value from a table
86
+
87
+ :param table: table to fetch the key from
88
+ :type table: Table
89
+ :param key_value: value of the primary key
90
+ :type key_value: Any
91
+ :return: the raw row of of the table
92
+ :rtype: Optional[Tuple]
58
93
"""
59
94
if table .primary_key is None :
60
95
raise ValueError (f"table { table .name } has no explicit primary key" )
@@ -64,12 +99,24 @@ def get_row_by_key(self, table: Table, key_value) -> Optional[Tuple]:
64
99
return rows [0 ]
65
100
66
101
def get_conditions_rows (self , table : Table ,
67
- selection : Optional [ Union [str , List [str ]]] = None ,
102
+ selection : Union [str , List [str ]] = '*' ,
68
103
conditions_list : Optional [List [Tuple [str , SQLConditionEnum , Any ]]] = None ,
69
- order_list : Optional [List [str ]] = None ) -> List :
70
- if selection is None :
71
- selection = '*'
72
- elif isinstance (selection , List ):
104
+ order_list : Optional [List [str ]] = None ) -> List [Tuple ]:
105
+ """
106
+ Select rows with optional conditions and optional order
107
+
108
+ :param table: table to select the rows from
109
+ :type table: Table
110
+ :param selection: list of column or SQL type selection
111
+ :type selection: Union[str, List[str]]
112
+ :param conditions_list: list of conditions to select the row
113
+ :type conditions_list: Optional[List[Tuple[str, SQLConditionEnum, Any]]]
114
+ :param order_list: List of SQL type order by
115
+ :type order_list: Optional[List[str]]
116
+ :return: the selected rows
117
+ :rtype: List[Tuple]
118
+ """
119
+ if isinstance (selection , List ):
73
120
selection = ',' .join (selection )
74
121
if conditions_list is None :
75
122
conditions_list = []
@@ -80,10 +127,33 @@ def get_conditions_rows(self, table: Table,
80
127
execution_cmd = self ._add_order (execution_cmd , order_list = order_list )
81
128
return self ._fetch_rows (execution_cmd )
82
129
83
- def get_all_rows (self , table : Table ) -> List :
130
+ def get_all_rows (self , table : Table ) -> List [Tuple ]:
131
+ """
132
+ Get all the rows of a table
133
+
134
+ :param table: table to get the rows from
135
+ :type table: Table
136
+ :return: all the rows of the table
137
+ :rtype: List[Tuple]
138
+ """
84
139
return self .get_conditions_rows (table )
85
140
86
141
def add_row (self , table : Table , row : Tuple , auto_commit : bool = True , update_if_exists : bool = False ):
142
+ """
143
+ Add a row to a table
144
+
145
+ :param table: table to add a row to
146
+ :type table: Table
147
+ :param row: values to add to the database
148
+ :type row: Tuple
149
+ :param auto_commit: if the database state should be saved after the changes
150
+ :type auto_commit: bool
151
+ :param update_if_exists: if an integrity error is raised and this parameter is true,
152
+ will update the existing row
153
+ :type update_if_exists: bool
154
+ :return: None
155
+ :rtype: None
156
+ """
87
157
row_s = ", " .join (f"'{ v } '" for v in row )
88
158
row_s = f'({ row_s } )'
89
159
execution_order = f"INSERT INTO { table .name } VALUES { row_s } "
@@ -100,15 +170,45 @@ def add_row(self, table: Table, row: Tuple, auto_commit: bool = True, update_if_
100
170
if update_if_exists :
101
171
self .update_row (table , row , auto_commit )
102
172
else :
173
+ existing_row = self .get_row_by_key (table , row [0 ])
174
+ msg = f"tried to insert { row } in the table { table .name } but the row is occupied: { existing_row } "
175
+ self .logger .error (msg )
103
176
raise err
104
177
105
178
def add_rows (self , table : Table , rows : List [Tuple ], auto_commit : bool = True , update_if_exists : bool = False ):
179
+ """
180
+ Add several rows to a table
181
+
182
+ :param table: table to add a row to
183
+ :type table: Table
184
+ :param rows: list of values to add to the database
185
+ :type rows: List[Tuple]
186
+ :param auto_commit: if the database state should be saved after the changes
187
+ :type auto_commit: bool
188
+ :param update_if_exists: if an integrity error is raised and this parameter is true,
189
+ will update the existing row
190
+ :type update_if_exists: bool
191
+ :return: None
192
+ :rtype: None
193
+ """
106
194
for row in rows :
107
195
self .add_row (table , row , auto_commit = False , update_if_exists = update_if_exists )
108
196
if auto_commit :
109
197
self .commit ()
110
198
111
199
def update_row (self , table : Table , row : Tuple , auto_commit = True ):
200
+ """
201
+ Update the value of a row in a table
202
+
203
+ :param table: table to get updated
204
+ :type table: Table
205
+ :param row: values to update
206
+ :type row: Tuple
207
+ :param auto_commit: if the database state should be saved after the changes
208
+ :type auto_commit: bool
209
+ :return: None
210
+ :rtype: None
211
+ """
112
212
row_s = ", " .join (f"{ n } = { v } " for n , v in zip (table .columns_names , row ))
113
213
execution_order = f"UPDATE { table .name } SET { row_s } WHERE { table .primary_key } = { row [0 ]} "
114
214
self .db_cursor .execute (execution_order )
@@ -117,20 +217,23 @@ def update_row(self, table: Table, row: Tuple, auto_commit=True):
117
217
118
218
def create_table (self , table : Table ):
119
219
"""
120
- create a table in the database
220
+ Create a table in the database
221
+
121
222
:param table: Table instance with the config of the table to create
122
- :return:
223
+ :type table: Table
224
+ :return: None
225
+ :rtype: None
123
226
"""
124
227
create_cmd = self .get_create_cmd (table )
125
228
self .db_cursor .execute (create_cmd )
126
229
self .db_conn .commit ()
127
230
128
231
def drop_table (self , table : Union [Table , str ]):
129
232
"""
130
- delete a table from the database
233
+ Delete a table from the database
131
234
132
235
:param table: table or table name to drop
133
- :type table: str or Table instance
236
+ :type table: Union[ Table, str]
134
237
:return: None
135
238
:rtype: None
136
239
"""
@@ -142,7 +245,7 @@ def drop_table(self, table: Union[Table, str]):
142
245
143
246
def drop_all_tables (self ):
144
247
"""
145
- drop all the tables existing in the database
248
+ Drop all the tables existing in the database
146
249
147
250
:return: None
148
251
:rtype: None
@@ -154,7 +257,7 @@ def drop_all_tables(self):
154
257
155
258
def get_all_tables (self ) -> List [Tuple ]:
156
259
"""
157
- return all the tables existing in the database
260
+ Return all the tables existing in the database
158
261
159
262
:return: tables descriptions
160
263
:rtype: List[Tuple]
@@ -164,19 +267,24 @@ def get_all_tables(self) -> List[Tuple]:
164
267
165
268
def commit (self ):
166
269
"""
167
- submit and save the database state
168
- :return:
270
+ Submit and save the database state
271
+
272
+ :return: None
273
+ :rtype: None
169
274
"""
170
275
self .db_conn .commit ()
171
276
172
277
@staticmethod
173
278
def _add_conditions (execution_cmd : str , conditions_list : List [Tuple [str , SQLConditionEnum , Any ]]):
174
279
"""
175
- add a list of condition to an SQL command
280
+ Add a list of condition to an SQL command
281
+
176
282
:param execution_cmd: SQL command without 'WHERE' statement
177
283
:type execution_cmd: str
178
- :param conditions_list:
179
- :return:
284
+ :param conditions_list: List of condition to add to the SQL command
285
+ :type conditions_list: List[Tuple[str, SQLConditionEnum, Any]]
286
+ :return: the augmented command
287
+ :rtype: str
180
288
"""
181
289
if len (conditions_list ):
182
290
add_cmd = ' WHERE'
@@ -189,14 +297,14 @@ def _add_conditions(execution_cmd: str, conditions_list: List[Tuple[str, SQLCond
189
297
@staticmethod
190
298
def _add_order (execution_cmd : str , order_list : List [str ]):
191
299
"""
192
- add an order specification to an SQL command
300
+ Add an order specification to an SQL command
193
301
194
302
:param execution_cmd: SQL command without 'ORDER BY' statement
195
303
:type execution_cmd: str
196
- :param order_list:
197
- :type order_list:
198
- :return:
199
- :rtype:
304
+ :param order_list: SQL order
305
+ :type order_list: List[str]
306
+ :return: the augmented command
307
+ :rtype: str
200
308
"""
201
309
if len (order_list ):
202
310
add_cmd = ' ORDER BY'
@@ -207,11 +315,14 @@ def _add_order(execution_cmd: str, order_list: List[str]):
207
315
return execution_cmd
208
316
209
317
@staticmethod
210
- def get_create_cmd (table : Table ):
318
+ def get_create_cmd (table : Table ) -> str :
211
319
"""
212
- return the command in string format to create a table in the database
320
+ Return the command in string format to create a table in the database
321
+
213
322
:param table: Table instance with the config if the table to create
323
+ :type table: Table
214
324
:return: execution command for the table creation
325
+ :rtype: str
215
326
"""
216
327
cmd = ""
217
328
if table .primary_key is not None :
0 commit comments