feat(backend): add the db connection

This commit is contained in:
2025-08-20 15:08:30 -04:00
parent 7b64dbe150
commit 8f0dc0d658
13 changed files with 375 additions and 1 deletions

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.12.4

185
backend/.gitignore vendored Normal file
View File

@@ -0,0 +1,185 @@
# --------------------------------------------------------------
# Python / FastAPI core
# --------------------------------------------------------------
# Bytecompiled / optimized Python files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
build/
dist/
*.egg-info/
*.egg
*.whl
pip-wheel-metadata/
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
*.gcov
*.gcda
*.gcno
.pytest_cache/
pytestdebug.log
# Jupyter / IPython
.ipynb_checkpoints
profile_default/
ipython_config.py
# --------------------------------------------------------------
# Virtual environments & environment files
# --------------------------------------------------------------
# Virtualenv / venv / conda environments
env/
venv/
ENV/
VENV/
.venv/
.pyenv/
conda-env/
conda-requirements.txt
# Environment variable files (keep secrets out of VCS)
.env
.env.* # e.g. .env.dev, .env.prod
.envrc
.env.local
.env.development
.env.production
# --------------------------------------------------------------
# FastAPI / ASGI / Uvicorn specifics
# --------------------------------------------------------------
# Uvicorn log files (if you redirect logs to files)
uvicorn.log
uvicorn-access.log
# FastAPI generated OpenAPI / Swagger UI files (if you commit them)
openapi.json
swagger.json
# --------------------------------------------------------------
# Database / Alembic migrations
# --------------------------------------------------------------
# SQLite database files (often used in dev)
*.sqlite3
*.db
*.db-journal
# Alembic migration scripts (keep the folder but ignore compiled artifacts)
alembic/versions/*.pyc
alembic/versions/__pycache__/
# --------------------------------------------------------------
# Static & media assets
# --------------------------------------------------------------
# Uploads / generated media (usually served by a CDN or separate storage)
media/
uploads/
staticfiles/
static/ # keep if you have a folder you *do* want committed, otherwise ignore subfolders
# --------------------------------------------------------------
# Docker / CI / Deployment
# --------------------------------------------------------------
# Docker files that you might generate locally
docker-compose.override.yml
Dockerfile.dev
# Docker volumes / data
docker-data/
.docker/
# GitHub Actions / CI caches
.github/workflows/*.log
# --------------------------------------------------------------
# IDE / Editor specific
# --------------------------------------------------------------
# VS Code
.vscode/
# PyCharm / IntelliJ
.idea/
*.iml
*.iws
*.ipr
# Sublime Text
*.sublime-project
*.sublime-workspace
# Eclipse / VS
.project
.pydevproject
# Emacs / Vim
*~
\#*\#
.*.swp
.*.swo
.#*
.session
*.un~
*.orig
*.bak
*.tmp
# --------------------------------------------------------------
# OS generated files
# --------------------------------------------------------------
# macOS
.DS_Store
.AppleDouble
.LSOverride
# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
# Linux
*~
.nfs*
# --------------------------------------------------------------
# Miscellaneous
# --------------------------------------------------------------
# Logs
*.log
log/
logs/
# Documentation build artifacts (Sphinx, MkDocs, etc.)
docs/_build/
site/
# Backup files
*.bak
*.backup
*.old
# sqlite db
database.db
database.db-journal

View File

@@ -1 +0,0 @@
-- SQLite

View File

@@ -0,0 +1,3 @@
# database/__init__.py
from .connection import DatabaseConnection
from .repository import Repository

View File

@@ -0,0 +1,24 @@
import sqlite3
from typing import List, Tuple
class DatabaseConnection:
def __init__(self, db_name: str):
self.conn = sqlite3.connect(db_name)
self.cursor = self.conn.cursor()
def close_connection(self):
self.conn.close()
def execute_query(self, query: str, params: Tuple = None):
if params:
self.cursor.execute(query, params)
else:
self.cursor.execute(query)
self.conn.commit()
def execute_query_with_return(self, query: str, params: Tuple = None):
if params:
self.cursor.execute(query, params)
else:
self.cursor.execute(query)
return self.cursor.fetchall()

View File

@@ -0,0 +1,6 @@
# database/models/__init__.py
from .classification import Classification
from .member import Member
from .service_type import ServiceType
from .service import Service
from .service_availability import ServiceAvailability

View File

@@ -0,0 +1,14 @@
from ..connection import DatabaseConnection
class Classification:
def __init__(self, classification_name: str):
self.classification_name = classification_name
def save(self, db: DatabaseConnection):
query = "INSERT INTO Classifications (ClassificationName) VALUES (?)"
db.execute_query(query, (self.classification_name,))
@classmethod
def get_all(cls, db: DatabaseConnection):
query = "SELECT * FROM Classifications"
return db.execute_query_with_return(query)

View File

@@ -0,0 +1,19 @@
from ..connection import DatabaseConnection
class Member:
def __init__(self, first_name: str, last_name: str, email: str, phone_number: str, classification_id: int, notes: str = None):
self.first_name = first_name
self.last_name = last_name
self.email = email
self.phone_number = phone_number
self.classification_id = classification_id
self.notes = notes
def save(self, db: DatabaseConnection):
query = "INSERT INTO Members (FirstName, LastName, Email, PhoneNumber, ClassificationId, Notes) VALUES (?, ?, ?, ?, ?, ?)"
db.execute_query(query, (self.first_name, self.last_name, self.email, self.phone_number, self.classification_id, self.notes))
@classmethod
def get_all(cls, db: DatabaseConnection):
query = "SELECT * FROM Members"
return db.execute_query_with_return(query)

View File

@@ -0,0 +1,15 @@
from ..connection import DatabaseConnection
class Service:
def __init__(self, service_type_id: int, service_date: str):
self.service_type_id = service_type_id
self.service_date = service_date
def save(self, db: DatabaseConnection):
query = "INSERT INTO Services (ServiceTypeId, ServiceDate) VALUES (?, ?)"
db.execute_query(query, (self.service_type_id, self.service_date))
@classmethod
def get_all(cls, db: DatabaseConnection):
query = "SELECT * FROM Services"
return db.execute_query_with_return(query)

View File

@@ -0,0 +1,15 @@
from ..connection import DatabaseConnection
class ServiceAvailability:
def __init__(self, member_id: int, service_type_id: int):
self.member_id = member_id
self.service_type_id = service_type_id
def save(self, db: DatabaseConnection):
query = "INSERT INTO ServiceAvailability (MemberId, ServiceTypeId) VALUES (?, ?)"
db.execute_query(query, (self.member_id, self.service_type_id))
@classmethod
def get_all(cls, db: DatabaseConnection):
query = "SELECT * FROM ServiceAvailability"
return db.execute_query_with_return(query)

View File

@@ -0,0 +1,14 @@
from ..connection import DatabaseConnection
class ServiceType:
def __init__(self, type_name: str):
self.type_name = type_name
def save(self, db: DatabaseConnection):
query = "INSERT INTO ServiceTypes (TypeName) VALUES (?)"
db.execute_query(query, (self.type_name,))
@classmethod
def get_all(cls, db: DatabaseConnection):
query = "SELECT * FROM ServiceTypes"
return db.execute_query_with_return(query)

View File

@@ -0,0 +1,41 @@
from .connection import DatabaseConnection
from .models import Classification, Member, ServiceType, Service, ServiceAvailability
class Repository:
def __init__(self, db: DatabaseConnection):
self.db = db
def create_classification(self, classification_name: str):
classification = Classification(classification_name)
classification.save(self.db)
def create_member(self, first_name: str, last_name: str, email: str, phone_number: str, classification_id: int, notes: str = None):
member = Member(first_name, last_name, email, phone_number, classification_id, notes)
member.save(self.db)
def create_service_type(self, type_name: str):
service_type = ServiceType(type_name)
service_type.save(self.db)
def create_service(self, service_type_id: int, service_date: str):
service = Service(service_type_id, service_date)
service.save(self.db)
def create_service_availability(self, member_id: int, service_type_id: int):
service_availability = ServiceAvailability(member_id, service_type_id)
service_availability.save(self.db)
def get_all_classifications(self):
return Classification.get_all(self.db)
def get_all_members(self):
return Member.get_all(self.db)
def get_all_service_types(self):
return ServiceType.get_all(self.db)
def get_all_services(self):
return Service.get_all(self.db)
def get_all_service_availability(self):
return ServiceAvailability.get_all(self.db)

38
backend/main.py Normal file
View File

@@ -0,0 +1,38 @@
from database.repository import Repository
from database.connection import DatabaseConnection
def main():
db = DatabaseConnection("database.db")
repository = Repository(db)
# Retrieve data
classifications = repository.get_all_classifications()
members = repository.get_all_members()
service_types = repository.get_all_service_types()
services = repository.get_all_services()
service_availability = repository.get_all_service_availability()
print("Classifications:")
for classification in classifications:
print(classification)
print("\nMembers:")
for member in members:
print(member)
print("\nService Types:")
for service_type in service_types:
print(service_type)
print("\nServices:")
for service in services:
print(service)
print("\nService Availability:")
for availability in service_availability:
print(availability)
db.close_connection()
if __name__ == "__main__":
main()