Files
v2-Docker/lizenzserver/repositories/base.py
Claude Project Manager 0d7d888502 Initial commit
2025-07-05 17:51:16 +02:00

94 Zeilen
3.4 KiB
Python

from abc import ABC, abstractmethod
from typing import Optional, List, Dict, Any
import psycopg2
from psycopg2.extras import RealDictCursor
from contextlib import contextmanager
import logging
logger = logging.getLogger(__name__)
class BaseRepository(ABC):
"""Base repository with common database operations"""
def __init__(self, db_url: str):
self.db_url = db_url
@contextmanager
def get_db_connection(self):
"""Get database connection with automatic cleanup"""
conn = None
try:
conn = psycopg2.connect(self.db_url)
yield conn
except Exception as e:
if conn:
conn.rollback()
logger.error(f"Database error: {e}")
raise
finally:
if conn:
conn.close()
@contextmanager
def get_db_cursor(self, conn):
"""Get database cursor with dict results"""
cursor = None
try:
cursor = conn.cursor(cursor_factory=RealDictCursor)
yield cursor
finally:
if cursor:
cursor.close()
def execute_query(self, query: str, params: tuple = None) -> List[Dict[str, Any]]:
"""Execute SELECT query and return results"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
cursor.execute(query, params)
return cursor.fetchall()
def execute_one(self, query: str, params: tuple = None) -> Optional[Dict[str, Any]]:
"""Execute query and return single result"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
cursor.execute(query, params)
return cursor.fetchone()
def execute_insert(self, query: str, params: tuple = None) -> Optional[str]:
"""Execute INSERT query and return ID"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
cursor.execute(query + " RETURNING id", params)
result = cursor.fetchone()
conn.commit()
return result['id'] if result else None
def execute_update(self, query: str, params: tuple = None) -> int:
"""Execute UPDATE query and return affected rows"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
cursor.execute(query, params)
affected = cursor.rowcount
conn.commit()
return affected
def execute_delete(self, query: str, params: tuple = None) -> int:
"""Execute DELETE query and return affected rows"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
cursor.execute(query, params)
affected = cursor.rowcount
conn.commit()
return affected
def execute_batch(self, queries: List[tuple]) -> None:
"""Execute multiple queries in a transaction"""
with self.get_db_connection() as conn:
with self.get_db_cursor(conn) as cursor:
try:
for query, params in queries:
cursor.execute(query, params)
conn.commit()
except Exception as e:
conn.rollback()
raise