Files
gander/web_server/database/database.py

67 lines
2.4 KiB
Python

import sqlite3
import os
class Database:
def __init__(self) -> None:
self._db = os.path.join(os.path.abspath(os.path.dirname(__file__)), "app.db")
self._conn = None
self.cursor = None
self.create_connection()
def __enter__(self):
"""Returns db on using with clause"""
return self
def __exit__(self, exc_type, exc_value, traceback):
"""Closes db connection after with clause"""
self.close_connection()
def create_connection(self) -> None:
"""Create a database connection if not already established."""
if self._conn is None:
self._conn = sqlite3.connect(self._db)
self._conn.row_factory = sqlite3.Row
self.cursor = self._conn.cursor()
def close_connection(self) -> None:
"""Close the database connection."""
if self._conn:
self._conn.close()
self._conn = None
self.cursor = None
def fetchall(self, query: str, parameters=None) -> list[dict]:
"""Fetch all records from the database."""
self.create_connection()
self.cursor.execute(query, parameters or ())
result = self.cursor.fetchall()
return self.convert_to_list_dict(result)
def fetchone(self, query: str, parameters=None) -> dict | None:
"""Fetch one record from the database."""
self.create_connection()
self.cursor.execute(query, parameters or ())
result = self.cursor.fetchone()
return self.convert_to_list_dict(result) if result else None
def execute(self, query: str, parameters=None) -> None:
"""Execute an INSERT, UPDATE, or DELETE command and commit changes."""
self.create_connection()
try:
self.cursor.execute(query, parameters or ())
self._conn.commit()
except sqlite3.DatabaseError as e:
print(f"Database error: {e}")
raise
def get_last_insert_id(self) -> int:
"""Get the ID of the last inserted row."""
return self.cursor.lastrowid if self.cursor else None
def convert_to_list_dict(self, result):
"""Convert query result to a list of dictionaries."""
if not result:
return []
columns = [desc[0] for desc in self.cursor.description]
return [dict(zip(columns, row)) for row in result] if isinstance(result, list) else dict(zip(columns, result))