def create(self, user, repository, commit_id=None, local_site=None, create_from_commit_id=False): """ Creates a new review request, optionally filling in fields based off a change number. """ if commit_id and create_from_commit_id: # Try both the new commit_id and old changenum versions try: review_request = self.get(commit_id=commit_id, repository=repository) raise ChangeNumberInUseError(review_request) except ObjectDoesNotExist: pass try: review_request = self.get(changenum=int(commit_id), repository=repository) raise ChangeNumberInUseError(review_request) except (ObjectDoesNotExist, TypeError, ValueError): pass diffset_history = DiffSetHistory() diffset_history.save() review_request = self.model(submitter=user, status='P', public=False, repository=repository, diffset_history=diffset_history, local_site=local_site) if commit_id: if create_from_commit_id: try: review_request.update_from_commit_id(commit_id) except Exception, e: review_request.commit_id = commit_id logging.error( 'Unable to update new review request from ' 'commit ID %s: %s', commit_id, e, exc_info=1) else: review_request.commit_id = commit_id
def create(self, user, repository, changenum=None, local_site=None): """ Creates a new review request, optionally filling in fields based off a change number. """ if changenum: try: review_request = self.get(changenum=changenum, repository=repository) raise ChangeNumberInUseError(review_request) except ObjectDoesNotExist: pass diffset_history = DiffSetHistory() diffset_history.save() review_request = super(ReviewRequestManager, self).create(submitter=user, status='P', public=False, repository=repository, diffset_history=diffset_history, local_site=local_site) if changenum: review_request.update_from_changenum(changenum) review_request.save() if local_site: # We want to atomically set the local_id to be a monotonically # increasing ID unique to the local_site. This isn't really possible # in django's DB layer, so we have to drop back to pure SQL and then # reload the model. from reviewboard.reviews.models import ReviewRequest db = router.db_for_write(ReviewRequest) cursor = connections[db].cursor() cursor.execute( 'UPDATE %(table)s SET' ' local_id = COALESCE(' ' (SELECT MAX(local_id) from' ' (SELECT local_id FROM %(table)s' ' WHERE local_site_id = %(local_site_id)s) as x' ' ) + 1,' ' 1),' ' local_site_id = %(local_site_id)s' ' WHERE %(table)s.id = %(id)s' % { 'table': ReviewRequest._meta.db_table, 'local_site_id': local_site.pk, 'id': review_request.pk, }) review_request = ReviewRequest.objects.get(pk=review_request.pk) return review_request
def create(self, user, repository, commit_id=None, local_site=None, create_from_commit_id=False): """ Creates a new review request, optionally filling in fields based off a commit ID. """ from reviewboard.reviews.models import ReviewRequestDraft if commit_id: # Try both the new commit_id and old changenum versions try: review_request = self.get(commit_id=commit_id, repository=repository) raise ChangeNumberInUseError(review_request) except ObjectDoesNotExist: pass try: draft = ReviewRequestDraft.objects.get( commit_id=commit_id, review_request__repository=repository) raise ChangeNumberInUseError(draft.review_request) except ObjectDoesNotExist: pass try: review_request = self.get(changenum=int(commit_id), repository=repository) raise ChangeNumberInUseError(review_request) except (ObjectDoesNotExist, TypeError, ValueError): pass diffset_history = DiffSetHistory() diffset_history.save() review_request = self.model(submitter=user, status='P', public=False, repository=repository, diffset_history=diffset_history, local_site=local_site) if commit_id and not create_from_commit_id: review_request.commit_id = commit_id review_request.validate_unique() review_request.save() if commit_id and create_from_commit_id: try: draft = ReviewRequestDraft.objects.create( review_request=review_request) draft.update_from_commit_id(commit_id) draft.save() draft.add_default_reviewers() except Exception as e: review_request.commit_id = commit_id review_request.save(update_fields=['commit_id']) logging.error( 'Unable to update new review request from ' 'commit ID %s: %s', commit_id, e, exc_info=1) if local_site: # We want to atomically set the local_id to be a monotonically # increasing ID unique to the local_site. This isn't really # possible in django's DB layer, so we have to drop back to pure # SQL and then reload the model. from reviewboard.reviews.models import ReviewRequest db = router.db_for_write(ReviewRequest) cursor = connections[db].cursor() cursor.execute( 'UPDATE %(table)s SET' ' local_id = COALESCE(' ' (SELECT MAX(local_id) from' ' (SELECT local_id FROM %(table)s' ' WHERE local_site_id = %(local_site_id)s) as x' ' ) + 1,' ' 1),' ' local_site_id = %(local_site_id)s' ' WHERE %(table)s.id = %(id)s' % { 'table': ReviewRequest._meta.db_table, 'local_site_id': local_site.pk, 'id': review_request.pk, }) transaction.commit() review_request = ReviewRequest.objects.get(pk=review_request.pk) # Ensure that a draft exists, so that users will be prompted to publish # the new review request. ReviewRequestDraft.create(review_request) return review_request
def create(self, user, repository, commit_id=None, local_site=None, create_from_commit_id=False, create_with_history=False): """Create a new review request. Args: user (django.contrib.auth.models.User): The user creating the review request. They will be tracked as the submitter. repository (reviewboard.scmtools.Models.Repository): The repository, if any, the review request is associated with. If ``None``, diffs cannot be added to the review request. commit_id (unicode, optional): An optional commit ID. local_site (reviewboard.site.models.LocalSite, optional): An optional LocalSite to associate the review request with. create_from_commit_id (bool, optional): Whether or not the given ``commit_id`` should be used to pre-populate the review request data. If ``True``, the given ``repository`` will be used to do so. create_with_history (bool, optional): Whether or not the created review request will support attaching multiple commits per diff revision. If ``False``, it will not be possible to use the :py:class:`~reviewboard.webapi.resources.diff.DiffResource` to upload diffs; the :py:class:`~reviewboard.webapi.resources.DiffCommitResource` must be used instead. Returns: reviewboard.reviews.models.review_request.ReviewRequest: The created review request. Raises: reviewboard.scmtools.errors.ChangeNumberInUseError: The commit ID is already in use by another review request. ValueError: An invalid value was passed for an argument. """ from reviewboard.reviews.models import ReviewRequestDraft if commit_id: # Try both the new commit_id and old changenum versions try: review_request = self.get(commit_id=commit_id, repository=repository) raise ChangeNumberInUseError(review_request) except ObjectDoesNotExist: pass try: draft = ReviewRequestDraft.objects.get( commit_id=commit_id, review_request__repository=repository) raise ChangeNumberInUseError(draft.review_request) except ObjectDoesNotExist: pass try: review_request = self.get(changenum=int(commit_id), repository=repository) raise ChangeNumberInUseError(review_request) except (ObjectDoesNotExist, TypeError, ValueError): pass if create_with_history: if repository is None: raise ValueError('create_with_history requires a repository.') elif create_from_commit_id: raise ValueError( 'create_from_commit_id and create_with_history cannot ' 'both be set to True.') elif not repository.scmtool_class.supports_history: raise ValueError( 'This repository does not support review requests created ' 'with history.') # Create the review request. We're not going to actually save this # until we're confident we have all the data we need. review_request = self.model(submitter=user, status='P', public=False, repository=repository, diffset_history=DiffSetHistory(), local_site=local_site) review_request.created_with_history = create_with_history if commit_id: review_request.commit = commit_id review_request.validate_unique() draft = None if commit_id and create_from_commit_id: try: draft = ReviewRequestDraft(review_request=review_request) draft.update_from_commit_id(commit_id) except Exception as e: logging.exception( 'Unable to update new review request from ' 'commit ID %s on repository ID=%s: %s', commit_id, repository.pk, e) raise # Now that we've guaranteed we have everything needed for this review # request, we can save all related objects and re-attach (since the # "None" IDs are cached). review_request.diffset_history.save() review_request.diffset_history = review_request.diffset_history review_request.save() if draft: draft.review_request = review_request draft.save() draft.add_default_reviewers() if local_site: # We want to atomically set the local_id to be a monotonically # increasing ID unique to the local_site. This isn't really # possible in django's DB layer, so we have to drop back to pure # SQL and then reload the model. from reviewboard.reviews.models import ReviewRequest with transaction.atomic(): # TODO: Use the cursor as a context manager when we move over # to Django 1.7+. db = router.db_for_write(ReviewRequest) cursor = connections[db].cursor() cursor.execute( 'UPDATE %(table)s SET' ' local_id = COALESCE(' ' (SELECT MAX(local_id) from' ' (SELECT local_id FROM %(table)s' ' WHERE local_site_id = %(local_site_id)s) as x' ' ) + 1,' ' 1),' ' local_site_id = %(local_site_id)s' ' WHERE %(table)s.id = %(id)s' % { 'table': ReviewRequest._meta.db_table, 'local_site_id': local_site.pk, 'id': review_request.pk, }) cursor.close() review_request.local_id = (ReviewRequest.objects.filter( pk=review_request.pk).values_list('local_id', flat=True)[0]) # Ensure that a draft exists, so that users will be prompted to publish # the new review request. ReviewRequestDraft.create(review_request) return review_request
def create(self, user, repository, commit_id=None, local_site=None, create_from_commit_id=False): """ Creates a new review request, optionally filling in fields based off a commit ID. """ from reviewboard.reviews.models import ReviewRequestDraft if commit_id: # Try both the new commit_id and old changenum versions try: review_request = self.get(commit_id=commit_id, repository=repository) raise ChangeNumberInUseError(review_request) except ObjectDoesNotExist: pass try: draft = ReviewRequestDraft.objects.get( commit_id=commit_id, review_request__repository=repository) raise ChangeNumberInUseError(draft.review_request) except ObjectDoesNotExist: pass try: review_request = self.get(changenum=int(commit_id), repository=repository) raise ChangeNumberInUseError(review_request) except (ObjectDoesNotExist, TypeError, ValueError): pass # Create the review request. We're not going to actually save this # until we're confident we have all the data we need. review_request = self.model( submitter=user, status='P', public=False, repository=repository, diffset_history=DiffSetHistory(), local_site=local_site) if commit_id: review_request.commit = commit_id review_request.validate_unique() draft = None if commit_id and create_from_commit_id: try: draft = ReviewRequestDraft(review_request=review_request) draft.update_from_commit_id(commit_id) except Exception as e: logging.exception('Unable to update new review request from ' 'commit ID %s on repository ID=%s: %s', commit_id, repository.pk, e) raise # Now that we've guaranteed we have everything needed for this review # request, we can save all related objects and re-attach (since the # "None" IDs are cached). review_request.diffset_history.save() review_request.diffset_history = review_request.diffset_history review_request.save() if draft: draft.review_request = review_request draft.save() draft.add_default_reviewers() if local_site: # We want to atomically set the local_id to be a monotonically # increasing ID unique to the local_site. This isn't really # possible in django's DB layer, so we have to drop back to pure # SQL and then reload the model. from reviewboard.reviews.models import ReviewRequest with transaction.atomic(): # TODO: Use the cursor as a context manager when we move over # to Django 1.7+. db = router.db_for_write(ReviewRequest) cursor = connections[db].cursor() cursor.execute( 'UPDATE %(table)s SET' ' local_id = COALESCE(' ' (SELECT MAX(local_id) from' ' (SELECT local_id FROM %(table)s' ' WHERE local_site_id = %(local_site_id)s) as x' ' ) + 1,' ' 1),' ' local_site_id = %(local_site_id)s' ' WHERE %(table)s.id = %(id)s' % { 'table': ReviewRequest._meta.db_table, 'local_site_id': local_site.pk, 'id': review_request.pk, }) cursor.close() review_request.local_id = ( ReviewRequest.objects.filter(pk=review_request.pk) .values_list('local_id', flat=True)[0] ) # Ensure that a draft exists, so that users will be prompted to publish # the new review request. ReviewRequestDraft.create(review_request) return review_request