from .... import logger from ....constants import CREATED_PREFIX, DB, DBAuditLogActions, Tables from ....typings import AuditGroupID, AuditID, Rows, UserID logger = logger.new_logger(__name__) class Audits: """Class for interacting with audits data.""" def __init__(self, client): self.client = client async def get_id(self, audit_group_id: AuditGroupID, _type: str) -> AuditID | None: """Get audit ID from audit group ID and audit type. If the audit does not exist, return None. Args: audit_group_id: Audit group ID. _type: Audit type. """ query = f""" SELECT id FROM {Tables.AUDITS} WHERE `group` = %s AND `type` = %s """ audit = await self.client.db.execute_query_fetchone( query, (audit_group_id, _type) ) return audit[DB.ID] if audit else None async def list(self, limit=None) -> Rows: """List audits.""" query = f""" WITH AUDIT_CREATED AS ( SELECT AL.audit AS audit, AL.date_created_utc AS date_created_utc, AL.user AS user FROM {Tables.AUDITS_LOG} AL WHERE AL.action LIKE '{CREATED_PREFIX}%' ), AUDIT_COMPLETED AS ( SELECT AL.audit AS audit, AL.date_created_utc AS date_created_utc FROM {Tables.AUDITS_LOG} AL WHERE AL.action = '{DBAuditLogActions.COMPLETED}' ) SELECT AG.id AS `group`, A.id AS audit, A.type AS `type`, AUDIT_CREATED.user AS `user`, U.nickname AS `user_nickname`, AUDIT_CREATED.date_created_utc AS date_created_utc, AUDIT_COMPLETED.date_created_utc AS date_completed_utc FROM {Tables.AUDITS} A JOIN {Tables.AUDITS_GROUPS} AG ON A.`group` = AG.id LEFT JOIN AUDIT_CREATED ON A.id = AUDIT_CREATED.audit LEFT JOIN AUDIT_COMPLETED ON A.id = AUDIT_COMPLETED.audit LEFT JOIN {Tables.USERS} U ON AUDIT_CREATED.user = U.id """ if limit: query += f" LIMIT {int(limit)}" data = await self.client.db.execute_query_fetchall(query) return data or [] async def get_log( self, audit_id: int, action: str, *, details: str | None = None, row_count: int | None = None, user: UserID | None = None, ) -> None: """Log an audit action. Args: audit_id: Audit ID. action: Action performed. details: Action details. row_count: Number of rows affected. user: User ID performing the action. """ query = f""" INSERT INTO {Tables.AUDITS_LOG} (audit, action, details, row_count, date_created_utc, user) VALUES (%s, %s, %s, %s, UTC_TIMESTAMP(), %s) """ # Explicitly enforce action to be a string, just in case what's passed into # this method as action is not strictly a string (e.g. an enum). params = (audit_id, str(action), details, row_count, user) await self.client.db.execute_query_nofetch(query, params)