ThalamOS
a powerful Flask web application designed to enhance your storage management.
Loading...
Searching...
No Matches
Storage_connector.py
Go to the documentation of this file.
1"""
2StorageConnector Module
3
4This module provides functions to interact with a SQLite database for managing storage items.
5It includes functionalities to set up the database, create, fetch, delete, and search items,
6as well as export the data to a CSV file.
7
8Functions:
9- setup(): Sets up the database by creating the 'storage' table and
10 a trigger for automatic updating of the 'modification_time' column.
11- fetch_csv(): Fetches all data from the 'storage' table and
12 writes it to a CSV file named 'out.csv'.
13- fetch_item(item_id): Fetches an item from the storage database by its id.
14- delete_item(item_id): Deletes an item from the storage database based on the provided item id.
15- create_item(pos, typ, name, jsonData): Creates an item in the storage database.
16- search(search_term): Searches the storage database for entries that match the given search term.
17"""
18from typing import Annotated
19import csv
20import sqlite3
21import os
22
23from logger_config import logger
24
25
26db_path: Annotated[str, "path of database files"] = os.path.join(
27 os.path.dirname(__file__), "data/storage.db"
28)
29logger.info(f"Database path: {db_path}")
30mydb: Annotated[sqlite3.Connection, "helper object for database"] = sqlite3.connect(
31 db_path, check_same_thread=False
32)
33cursor = mydb.cursor()
34
35
36def setup() -> None:
37 """
38 Sets up the database by creating the 'storage' table and a trigger for automatic
39 updating of the 'modification_time' column.
40 The 'storage' table contains the following columns:
41 - id: INTEGER, primary key, autoincrement
42 - position: INTEGER
43 - type: sensor | screw | display | nail | display | cable | miscellaneous | Motor Driver
44 - name: TEXT
45 - info: TEXT
46 - modification_time: TIMESTAMP, defaults to the current timestamp
47 The trigger 'update_modification_time' ensures that the 'modification_time' column
48 is automatically updated to the current timestamp whenever a row in the 'storage'
49 table is updated.
50 Commits the changes to the database and prints a confirmation message.
51 """
52 cursor.execute(
53 """
54 CREATE TABLE IF NOT EXISTS storage (
55 id INTEGER PRIMARY KEY AUTOINCREMENT,
56 position INTEGER,
57 type TEXT,
58 name TEXT,
59 info TEXT,
60 modification_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
61 );
62 """
63 )
64
65 # trigger for automatic update of modification_time
66 cursor.execute(
67 """
68 CREATE TRIGGER IF NOT EXISTS update_modification_time
69 AFTER UPDATE ON storage
70 FOR EACH ROW
71 BEGIN
72 UPDATE storage
73 SET modification_time = CURRENT_TIMESTAMP
74 WHERE id = OLD.id;
75 END;
76 """
77 )
78 mydb.commit()
79 logger.info("Database setup complete and ready for service")
80
81
82def fetch_csv() -> None:
83 """
84 Fetches all data from the 'storage' table in the database and
85 writes it to a CSV file named 'out.csv'.
86 The function executes a SQL query to select all rows from the
87 'storage' table, writes the column headers
88 and all rows to the CSV file, and saves the file with UTF-8 encoding.
89 Raises:
90 Any exceptions raised by the database cursor execution or file operations.
91 """
92
93 cursor.execute("SELECT * FROM storage;")
94 with open("static/database.csv", "w", newline="", encoding="utf-8") as csv_file:
95 csv_writer = csv.writer(csv_file)
96 csv_writer.writerow([i[0] for i in cursor.description])
97 csv_writer.writerows(cursor.fetchall())
98
99
101 item_id,
102) -> Annotated[tuple, "tuple containing the item's data if found, otherwise None"]:
103 """
104 Fetch an item from the storage database by its id.
105 Args:
106 itemID (int): The id of the item to fetch.
107 Returns:
108 tuple: A tuple containing the item's data if found, otherwise None.
109 """
110
111 cursor.execute("select * From storage WHERE id=?;", (item_id,))
112 return cursor.fetchone()
113
114
115def delete_item(item_id) -> None:
116 """
117 Deletes an item from the storage database based on the provided item id.
118 Args:
119 itemID (int): The id of the item to be deleted from the storage.
120 Returns:
121 None
122 """
123
124 cursor.execute("DELETE FROM storage WHERE ID=?;", (item_id,))
125 mydb.commit()
126
127
128def create_item(pos, obj_type, name, json_data) -> None:
129 """
130 Creates an item in the storage database.
131 Args:
132 pos (int): The position of the item.
133 typ (str): The type of the item.
134 name (str): The name of the item.
135 jsonData (str): The JSON data associated with the item. If empty JSON object ("{}"),
136 no additional info is stored.
137 Returns:
138 None
139 """
140
141 logger.info(
142 "Creating item with position: {}, type: {}, name: {}, json_data: {}",
143 pos,
144 obj_type,
145 name,
146 json_data,
147 )
148 if json_data == "{}":
149 query = "INSERT INTO storage (position, type, name) VALUES (?, ?, ?);"
150 params = (pos, obj_type, name)
151 else:
152 query = "INSERT INTO storage (position, type, name, info) VALUES (?, ?, ?, ?);"
153 params = (pos, obj_type, name, json_data)
154 logger.debug(f"Executing query: {query} with params: {params}")
155 cursor.execute(query, params)
156 mydb.commit()
157
158
160 search_term,
161) -> Annotated[
162 list,
163 "list of tuples containing the rows from the database that match the search criteria",
164]:
165 """
166 Searches the storage database for entries that match the given search term.
167 Args:
168 searchTerm (str): The term to search for in the database. The term will be split
169 into individual words,
170 and each word will be used to search the 'type', 'name', and
171 'info' columns.
172 Returns:
173 list: A list of tuples containing the rows from the database that match the search criteria.
174 Returns None if there is an SQLite programming error.
175 Raises:
176 sqlite3.ProgrammingError: If there is an error executing the query.
177 """
178 try:
179 # Split searchTerm into single words
180 search_terms = search_term.split()
181
182 # create statement with placeholders for each search term
183 conditions = " AND ".join(
184 ["(type LIKE ? OR name LIKE ? OR info LIKE ?)" for _ in search_terms]
185 )
186 query = f"""
187 SELECT *
188 FROM storage
189 WHERE {conditions};
190 """
191
192 # create parameters for each placeholder
193 parameters = tuple(f"%{term}%" for term in search_terms for _ in range(3))
194
195 # Debugging: print query and parameters
196 logger.debug(f"Executing search query: {query} with parameters: {parameters}")
197
198 cursor.execute(query, parameters)
199 results = cursor.fetchall()
200
201 return results
202
203 except sqlite3.ProgrammingError as e:
204 logger.error(f"SQLite-Error: {str(e)}")
205 return None
206
207
208def update_item(item_id, pos, obj_type, name, json_data) -> None:
209 """
210 Updates an item in the storage database.
211 Args:
212 item_id (int): The id of the item to update.
213 pos (int): The new position of the item.
214 obj_type (str): The new type of the item.
215 name (str): The new name of the item.
216 json_data (str): The new JSON data associated with the item.
217 Returns:
218 None
219 """
220 logger.info(
221 "Updating item with id: {}, position: {}, type: {}, name: {}, json_data: {}",
222 item_id,
223 pos,
224 obj_type,
225 name,
226 json_data,
227 )
228 query = """
229 UPDATE storage
230 SET position = ?, type = ?, name = ?, info = ?
231 WHERE id = ?;
232 """
233 params = (pos, obj_type, name, json_data, item_id)
234 logger.debug(f"Executing query: {query} with params: {params}")
235 cursor.execute(query, params)
236 mydb.commit()
Annotated[ list, "list of tuples containing the rows from the database that match the search criteria",] search(search_term)
None create_item(pos, obj_type, name, json_data)
None delete_item(item_id)
Annotated[tuple, "tuple containing the item's data if found, otherwise None"] fetch_item(item_id)
None update_item(item_id, pos, obj_type, name, json_data)