Newer
Older
attend-cgi / attendance_app / database.py
"""Database access layer for user information."""

import sqlite3
from typing import Optional, Tuple


class UserDatabase:
    """Interface for user database access."""

    def lookup_user(self, user_id: str) -> Optional[Tuple]:
        """
        Look up user information by ID.

        Args:
            user_id: User login ID

        Returns:
            Tuple of (number, name_kanji, name_kana, depart_name, pos_code)
            or None if not found
        """
        raise NotImplementedError


class SQLiteUserDatabase(UserDatabase):
    """SQLite implementation of user database."""

    def __init__(self, db_path: str):
        """
        Initialize database connection.

        Args:
            db_path: Path to SQLite database file
        """
        self.db_path = db_path
        self.conn = None
        self.cursor = None

    def __enter__(self):
        """Context manager entry."""
        self.conn = sqlite3.connect(self.db_path)
        self.cursor = self.conn.cursor()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit."""
        if self.cursor:
            self.cursor.close()
        if self.conn:
            self.conn.close()

    def lookup_user(self, user_id: str) -> Optional[Tuple]:
        """
        Look up user information by ID.

        Args:
            user_id: User login ID

        Returns:
            Tuple of (number, name_kanji, name_kana, depart_name, pos_code)
            or None if not found
        """
        if not self.cursor:
            raise RuntimeError("Database not opened. Use as context manager.")

        query = """
            SELECT number, name_kanji, name_kana, depart_name, pos_code
            FROM user
            WHERE id = ?
        """
        result = self.cursor.execute(query, (user_id,))
        return result.fetchone()


class MockUserDatabase(UserDatabase):
    """Mock implementation for testing."""

    def __init__(self, user_data: dict):
        """
        Initialize with mock user data.

        Args:
            user_data: Dict mapping user_id to tuple of user info
        """
        self.user_data = user_data

    def lookup_user(self, user_id: str) -> Optional[Tuple]:
        """Look up user from mock data."""
        return self.user_data.get(user_id)