feat: implement Instagram clone SocialPhoto API
- FastAPI backend with SQLite database - JWT authentication (register, login) - User profiles with follow/unfollow - Posts with image upload and likes/dislikes - Comments with likes - Global and personalized feed - Comprehensive pytest test suite (37 tests) TASK-ID: 758f4029-702
This commit is contained in:
120
app/database.py
Normal file
120
app/database.py
Normal file
@@ -0,0 +1,120 @@
|
||||
"""Database module for SocialPhoto."""
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
DATABASE_PATH = Path(__file__).parent.parent / "socialphoto.db"
|
||||
|
||||
|
||||
def get_db_connection() -> sqlite3.Connection:
|
||||
"""Get a database connection with row factory."""
|
||||
conn = sqlite3.connect(DATABASE_PATH, check_same_thread=False)
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
|
||||
def get_db() -> sqlite3.Connection:
|
||||
"""Dependency for FastAPI routes."""
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
yield conn
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
"""Initialize the database with all tables."""
|
||||
conn = get_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Users table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
avatar_url TEXT DEFAULT '/static/default-avatar.png',
|
||||
bio TEXT DEFAULT '',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
# Posts table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
image_path TEXT NOT NULL,
|
||||
caption TEXT DEFAULT '',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
# Comments table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS comments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
post_id INTEGER NOT NULL REFERENCES posts(id),
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
content TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
# Likes table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS likes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
post_id INTEGER NOT NULL REFERENCES posts(id),
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(post_id, user_id)
|
||||
)
|
||||
""")
|
||||
|
||||
# Dislikes table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS dislikes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
post_id INTEGER NOT NULL REFERENCES posts(id),
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(post_id, user_id)
|
||||
)
|
||||
""")
|
||||
|
||||
# Follows table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS follows (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
follower_id INTEGER NOT NULL REFERENCES users(id),
|
||||
following_id INTEGER NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(follower_id, following_id)
|
||||
)
|
||||
""")
|
||||
|
||||
# Comment likes table
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS comment_likes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
comment_id INTEGER NOT NULL REFERENCES comments(id),
|
||||
user_id INTEGER NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(comment_id, user_id)
|
||||
)
|
||||
""")
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def row_to_dict(row: sqlite3.Row) -> dict:
|
||||
"""Convert a sqlite Row to a dictionary."""
|
||||
return dict(row)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
init_db()
|
||||
print("Database initialized successfully.")
|
||||
Reference in New Issue
Block a user