Initial commit
Dieser Commit ist enthalten in:
94
lizenzserver/repositories/base.py
Normale Datei
94
lizenzserver/repositories/base.py
Normale Datei
@ -0,0 +1,94 @@
|
||||
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
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren