"""Release Correction Model.""" from datetime import datetime from oto.error import ERROR_CODE_INTERNAL_ERROR from oto.response import create_error_response, create_not_found_response from oto.response import Response from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy import Enum from sqlalchemy import Integer from sqlalchemy.orm import relationship from product_workflow.connectors import mysql from product_workflow.constants import release_correction_status as rcs class ReleaseCorrection(mysql.BaseModel): """Model for Release Correction Model.""" __tablename__ = 'release_correction' release_correction_id = Column( Integer, primary_key=True, autoincrement=True, nullable=False) release_id = Column(Integer, nullable=False) status = Column( Enum(rcs.ACTIVE, rcs.SUBMITTED, rcs.APPLIED), nullable=False) last_updated = Column(DateTime, nullable=False) last_updated_by = Column(Integer, nullable=False) last_updated_type = Column(Enum('oa', 'vendor'), default='vendor') details = relationship( 'ReleaseCorrectionDetail', cascade='delete', lazy='joined') approval = relationship( 'ReleaseApprovalQueue', cascade='delete', lazy='joined') def to_dict(self): """Return a dict representation of this release correction.""" return { 'release_correction_id': self.release_correction_id, 'release_id': self.release_id, 'status': self.status, 'items': [detail.to_dict() for detail in self.details] } @mysql.wrap_db_errors def create(column_data): """Create a new release correction record. :param column_data: Column data to insert for the record. :return: Response containing the created release correction data. """ release_correction = ReleaseCorrection( release_id=column_data.get('release_id'), status=column_data.get('status'), last_updated=datetime.now(), last_updated_by=column_data.get('last_updated_by'), last_updated_type=column_data.get('last_updated_type') ) with mysql.db_session() as session: session.add(release_correction) session.flush() if not release_correction: return create_error_response( code=ERROR_CODE_INTERNAL_ERROR, message='Release correction could not be created') return Response( message=release_correction.to_dict(), status=201 ) @mysql.wrap_db_errors def update(release_correction_id, release_correction_data): """Update an existing release correction.""" # Prevent primary key from being updated. new_pk = release_correction_data.pop('release_correction_id', None) if new_pk: return create_error_response( code=ERROR_CODE_INTERNAL_ERROR, message='release_correction_id cannot be updated' ) with mysql.db_session() as session: existing_correction = session\ .query(ReleaseCorrection)\ .get(release_correction_id) if not existing_correction: return create_not_found_response( 'No release correction record found' ) elif release_correction_data: for prop_name, prop_value in release_correction_data.items(): setattr(existing_correction, prop_name, prop_value) existing_correction.last_updated = datetime.now() return Response( message=existing_correction.to_dict(), status=200 ) @mysql.wrap_db_errors def get_last_release_correction(release_id): """Get the most recent release correction for the given release.""" with mysql.db_session() as session: release_correction = get_last_correction_object(session, release_id) if not release_correction: return create_not_found_response( message='No release correction record found') return Response(message=release_correction.to_dict()) def get_last_correction_object(session, release_id, for_update=False): """Get the most recent release correction for the given release.""" query = session.query(ReleaseCorrection) \ .filter_by(release_id=release_id) \ .order_by(ReleaseCorrection.release_correction_id.desc()) if for_update: query = query.with_for_update() return query.first() @mysql.wrap_db_errors def get_release_correction(release_correction_id): """Return a release_correction record for a given id if found. Return a error response if not found. """ with mysql.db_session() as session: release_correction = session.query(ReleaseCorrection) \ .filter_by(release_correction_id=release_correction_id).first() session.close() return release_correction def get_correction_object(session, release_correction_id, for_update=False): """Get the release correction for the given id.""" query = session.query(ReleaseCorrection) \ .filter_by(release_correction_id=release_correction_id) if for_update: query = query.with_for_update() return query.first() @mysql.wrap_db_errors def delete_release_correction(release_correction): """Delete a release correction record.""" with mysql.db_session() as session: session.delete(release_correction) session.flush() return Response( message=dict(message='release correction deleted'), status=202 )